/****************************************************************************** * * * Function: * * * * Purpose: * * * * Parameters: * * * * Return value: * * * * Comments: * * * ******************************************************************************/ char *evaluate_jobnetrun(zbx_sock_t * sock, struct zbx_json_parse *jp, int *ret) { DB_RESULT result; DB_ROW row; struct zbx_json_parse jp_row; struct zbx_json_parse jp_row2; char *message = NULL; char value[MAX_STRING_LEN]; const char *p; const char *p2; const char *p3 = NULL; int version; int res; int i; int count; zbx_uint64_t inner_jobnet_id; static JOBARG_EXEC_REQUEST er; init_exec_request(&er); if (SUCCEED == zbx_json_value_by_name(jp, JA_PROTO_TAG_VERSION, value, sizeof(value))) { version = atoi(value); if (version != JA_PROTO_VALUE_VERSION_1) { ja_log("JATRAPPER200027", 0, NULL, 0, JA_PROTO_VALUE_VERSION_1); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [version] is not correct."); } } else { ja_log("JATRAPPER200028", 0, NULL, 0); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [version] not found"); } if (NULL == (p = zbx_json_pair_by_name(jp, JA_PROTO_TAG_DATA))) { ja_log("JATRAPPER200021", 0, NULL, 0); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [data] not found"); } else { if (FAIL == (*ret = zbx_json_brackets_open(p, &jp_row))) { ja_log("JATRAPPER200022", 0, NULL, 0); *ret = FAIL; return zbx_dsprintf(message, "Received message error: Cannot open [data] object"); } else { if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_USERNAME, value, sizeof(value))) { er.username = strdup(value); } else { ja_log("JATRAPPER200032", 0, NULL, 0); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [username] not found"); } if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_PASSWORD, value, sizeof(value))) { er.password = strdup(value); } else { ja_log("JATRAPPER200033", 0, NULL, 0); zbx_free(er.username); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [password] not found"); } if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_JOBNETID, value, sizeof(value))) { er.jobnetid = strdup(value); } else { ja_log("JATRAPPER200034", 0, NULL, 0); zbx_free(er.username); zbx_free(er.password); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [jobnetid] not found"); } if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_STARTTIME, value, sizeof(value))) { er.starttime = strdup(value); res = time_passed_check(er.starttime); if (res == FAIL) { zbx_free(er.username); zbx_free(er.password); zbx_free(er.jobnetid); zbx_free(er.starttime); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [start_time] already passed."); } } i = 0; if (NULL != (p2 = zbx_json_pair_by_name(&jp_row, JA_PROTO_TAG_ENV))) { if (FAIL == (*ret = zbx_json_brackets_open(p2, &jp_row2))) { ja_log("JATRAPPER200051", 0, er.jobnetid, 0); zbx_free(er.username); zbx_free(er.password); zbx_free(er.jobnetid); zbx_free(er.starttime); *ret = FAIL; return zbx_dsprintf(message, "Received message error: Cannot open [env] object"); } else { while (NULL != (p3 = zbx_json_pair_next(&jp_row2, p3, value, sizeof(value)))) { er.env[i] = strdup(value); zbx_json_value_by_name(&jp_row2, er.env[i], value, sizeof(value)); er.value[i] = strdup(value); i++; } er.env[i] = '\0'; } } if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_DETERRENCE, value, sizeof(value))) { er.deterrence = atoi(value); } if (SUCCEED == (job_exec_auth(er))) { DBbegin(); /* double check start-up suppression time specified */ if (er.starttime != NULL && er.deterrence == 1) { result = DBselect("select count(*) from ja_run_jobnet_table" " where scheduled_time = %s and jobnet_id = '%s' and run_type = %d", er.starttime, er.jobnetid, JA_JOBNET_RUN_TYPE_SCHEDULED); if (NULL == (row = DBfetch(result))) { zbx_snprintf(msgwork, sizeof(msgwork), "%s %s %d", er.starttime, er.jobnetid, JA_JOBNET_RUN_TYPE_SCHEDULED); ja_log("JATRAPPER200057", 0, er.jobnetid, 0, "ja_run_jobnet_table", msgwork); DBfree_result(result); DBrollback(); clean_exec_request(&er, i); *ret = FAIL; return zbx_dsprintf(message, "ja_run_jobnet_table select error."); } count = atoi(row[0]); DBfree_result(result); if (count > 0) { DBrollback(); clean_exec_request(&er, i); *ret = FAIL; return zbx_dsprintf(message, "Received message error: Double registration detection of time starting jobnet."); } } if (SUCCEED == (register_db_table(er, &inner_jobnet_id, i))) { DBcommit(); clean_exec_request(&er, i); return zbx_dsprintf(message, "Registry number : [" ZBX_FS_UI64 "]", inner_jobnet_id); } else { DBrollback(); clean_exec_request(&er, i); *ret = FAIL; return zbx_dsprintf(message, "ja_run_jobnet_table insert error."); } } else { clean_exec_request(&er, i); *ret = FAIL; return zbx_dsprintf(message, "Authentication failure."); } } } }
/****************************************************************************** * * * Function: get_hostid_by_host * * * * Purpose: check for host name and return hostid * * * * Parameters: host - [IN] require size 'HOST_HOST_LEN_MAX' * * * * Return value: SUCCEED - host is found * * FAIL - an error occurred or host not found * * * * Author: Alexander Vladishev * * * * Comments: NB! adds host to the database if it does not exist * * * ******************************************************************************/ static int get_hostid_by_host(const zbx_socket_t *sock, const char *host, const char *ip, unsigned short port, const char *host_metadata, zbx_uint64_t *hostid, char *error) { const char *__function_name = "get_hostid_by_host"; char *host_esc, dns[INTERFACE_DNS_LEN_MAX], *ch_error; DB_RESULT result; DB_ROW row; int ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() host:'%s'", __function_name, host); if (FAIL == zbx_check_hostname(host, &ch_error)) { zbx_snprintf(error, MAX_STRING_LEN, "invalid host name [%s]: %s", host, ch_error); zbx_free(ch_error); goto out; } host_esc = DBdyn_escape_string(host); result = #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL) DBselect( "select hostid,status,tls_accept,tls_issuer,tls_subject,tls_psk_identity" " from hosts" " where host='%s'" " and status in (%d,%d)" " and flags<>%d" " and proxy_hostid is null", host_esc, HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED, ZBX_FLAG_DISCOVERY_PROTOTYPE); #else DBselect( "select hostid,status,tls_accept" " from hosts" " where host='%s'" " and status in (%d,%d)" " and flags<>%d" " and proxy_hostid is null", host_esc, HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED, ZBX_FLAG_DISCOVERY_PROTOTYPE); #endif if (NULL != (row = DBfetch(result))) { if (HOST_STATUS_MONITORED == atoi(row[1])) { unsigned int tls_accept; tls_accept = (unsigned int)atoi(row[2]); if (0 == (tls_accept & sock->connection_type)) { zbx_snprintf(error, MAX_STRING_LEN, "connection of type \"%s\" is not allowed for host" " \"%s\"", zbx_tls_connection_type_name(sock->connection_type), host); goto done; } #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL) if (ZBX_TCP_SEC_TLS_CERT == sock->connection_type) { zbx_tls_conn_attr_t attr; if (SUCCEED != zbx_tls_get_attr_cert(sock, &attr)) { THIS_SHOULD_NEVER_HAPPEN; zbx_snprintf(error, MAX_STRING_LEN, "cannot get connection attributes for host" " \"%s\"", host); goto done; } /* simplified match, not compliant with RFC 4517, 4518 */ if ('\0' != *row[3] && 0 != strcmp(row[3], attr.issuer)) { zbx_snprintf(error, MAX_STRING_LEN, "certificate issuer does not match for" " host \"%s\"", host); goto done; } /* simplified match, not compliant with RFC 4517, 4518 */ if ('\0' != *row[4] && 0 != strcmp(row[4], attr.subject)) { zbx_snprintf(error, MAX_STRING_LEN, "certificate subject does not match for" " host \"%s\"", host); goto done; } } else if (ZBX_TCP_SEC_TLS_PSK == sock->connection_type) { zbx_tls_conn_attr_t attr; if (SUCCEED != zbx_tls_get_attr_psk(sock, &attr)) { THIS_SHOULD_NEVER_HAPPEN; zbx_snprintf(error, MAX_STRING_LEN, "cannot get connection attributes for host" " \"%s\"", host); goto done; } if (strlen(row[5]) != attr.psk_identity_len || 0 != memcmp(row[5], attr.psk_identity, attr.psk_identity_len)) { zbx_snprintf(error, MAX_STRING_LEN, "false PSK identity for host \"%s\"", host); goto done; } } #endif ZBX_STR2UINT64(*hostid, row[0]); ret = SUCCEED; } else zbx_snprintf(error, MAX_STRING_LEN, "host [%s] not monitored", host); } else { zbx_snprintf(error, MAX_STRING_LEN, "host [%s] not found", host); /* remove ::ffff: prefix from IPv4-mapped IPv6 addresses */ if (0 == strncmp("::ffff:", ip, 7) && SUCCEED == is_ip4(ip + 7)) ip += 7; zbx_alarm_on(CONFIG_TIMEOUT); zbx_gethost_by_ip(ip, dns, sizeof(dns)); zbx_alarm_off(); DBbegin(); if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER)) DBregister_host(0, host, ip, dns, port, host_metadata, (int)time(NULL)); else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY)) DBproxy_register_host(host, ip, dns, port, host_metadata); DBcommit(); } done: DBfree_result(result); zbx_free(host_esc); out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: process_rule * * * * Purpose: process single discovery rule * * * * Author: Eugene Grigorjev * * * ******************************************************************************/ static void process_rule(DB_DRULE *drule) { const char *__function_name = "process_rule"; DB_DHOST dhost; int host_status, now; unsigned short j[9]; unsigned int i, first, last, ip_dig; char ip[INTERFACE_IP_LEN_MAX], *start, *comma, *dash, *slash, dns[INTERFACE_DNS_LEN_MAX]; int invalid_range; #ifdef HAVE_IPV6 int ipv6; #endif zabbix_log(LOG_LEVEL_DEBUG, "In %s() rule:'%s' range:'%s'", __function_name, drule->name, drule->iprange); for (start = drule->iprange; '\0' != *start;) { invalid_range = 0; if (NULL != (comma = strchr(start, ','))) *comma = '\0'; zabbix_log(LOG_LEVEL_DEBUG, "%s() range:'%s'", __function_name, start); if (NULL != (dash = strchr(start, '-'))) *dash = '\0'; else if (NULL != (slash = strchr(start, '/'))) *slash = '\0'; if (SUCCEED == ip6_str2dig(start, j)) { #ifdef HAVE_IPV6 ipv6 = 1; if (NULL != dash) { if (1 != sscanf(dash + 1, "%hx", &j[8])) { invalid_range = 1; goto next; } first = j[7]; last = j[8]; } else if (NULL != slash) { unsigned short mask; if (1 != sscanf(slash + 1, "%hu", &j[8]) || 112 > j[8] || j[8] > 128) { invalid_range = 1; goto next; } mask = 0xffff << (128 - j[8]); first = j[7] & mask; last = 0xffff & (j[7] | ~mask); } else { first = j[7]; last = j[7]; } #else invalid_range = 2; goto next; #endif } else if (SUCCEED == ip4_str2dig(start, &ip_dig)) { #ifdef HAVE_IPV6 ipv6 = 0; #endif if (NULL != dash) { if (1 != sscanf(dash + 1, "%hu", &j[4]) || 255 < j[4]) { invalid_range = 1; goto next; } first = ip_dig; last = (ip_dig & 0xffffff00) + j[4]; } else if (NULL != slash) { unsigned int mask; if (1 != sscanf(slash + 1, "%hu", &j[4]) || 16 > j[4] || j[4] > 30) { invalid_range = 1; goto next; } mask = 0xffffffff << (32 - j[4]); first = (ip_dig & mask) + 1; last = (ip_dig | ~mask) - 1; } else { first = ip_dig; last = ip_dig; } } else { invalid_range = 1; goto next; } if (first > last) { invalid_range = 1; goto next; } for (i = first; i <= last; i++) { memset(&dhost, 0, sizeof(dhost)); host_status = -1; now = time(NULL); #ifdef HAVE_IPV6 switch (ipv6) { case 0: #endif zbx_snprintf(ip, sizeof(ip), "%u.%u.%u.%u", (i & 0xff000000) >> 24, (i & 0x00ff0000) >> 16, (i & 0x0000ff00) >> 8, i & 0x000000ff); #ifdef HAVE_IPV6 break; case 1: j[7] = i; ip6_dig2str(j, ip, sizeof(ip)); break; } #endif zabbix_log(LOG_LEVEL_DEBUG, "%s() ip:'%s'", __function_name, ip); alarm(CONFIG_TIMEOUT); zbx_gethost_by_ip(ip, dns, sizeof(dns)); alarm(0); if (drule->unique_dcheckid) process_checks(drule, &dhost, &host_status, ip, dns, 1); process_checks(drule, &dhost, &host_status, ip, dns, 0); DBbegin(); if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) discovery_update_host(&dhost, ip, host_status, now); else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY)) proxy_update_host(drule, ip, dns, host_status, now); DBcommit(); } next: if (NULL != dash) *dash = '-'; else if (NULL != slash) *slash = '/'; switch (invalid_range) { case 1: zabbix_log(LOG_LEVEL_WARNING, "discovery rule \"%s\": wrong format of IP range \"%s\"", drule->name, start); break; case 2: zabbix_log(LOG_LEVEL_WARNING, "discovery rule \"%s\": encountered IP range \"%s\"," " but IPv6 support not compiled in", drule->name, start); break; } if (NULL != comma) { *comma = ','; start = comma + 1; } else break; } zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: get_hostid_by_host * * * * Purpose: check for host name and return hostid * * * * Parameters: host - [IN] require size 'HOST_HOST_LEN_MAX' * * * * Return value: SUCCEED - host is found * * FAIL - an error occurred or host not found * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ static int get_hostid_by_host(const char *host, zbx_uint64_t *hostid, char *error) { char *host_esc; DB_RESULT result; DB_ROW row; int res = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In get_hostid_by_host() host:'%s'", host); if (FAIL == zbx_check_hostname(host)) { zbx_snprintf(error, MAX_STRING_LEN, "invalid host name [%s]", host); return res; } host_esc = DBdyn_escape_string(host); result = DBselect( "select hostid,status" " from hosts" " where host='%s'" " and status in (%d,%d)" " and proxy_hostid=0" DB_NODE, host_esc, HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED, DBnode_local("hostid")); if (NULL != (row = DBfetch(result))) { if (HOST_STATUS_MONITORED == atoi(row[1])) { ZBX_STR2UINT64(*hostid, row[0]); res = SUCCEED; } else zbx_snprintf(error, MAX_STRING_LEN, "host [%s] not monitored", host); } else { zbx_snprintf(error, MAX_STRING_LEN, "host [%s] not found", host); DBbegin(); if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) { DBregister_host(0, host, (int)time(NULL)); } else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY)) { DBproxy_register_host(host); } DBcommit(); } DBfree_result(result); zbx_free(host_esc); return res; }
static void update_maintenance_hosts(zbx_host_maintenance_t *hm, int hm_count, int now) { typedef struct { zbx_uint64_t hostid; int maintenance_from; void *next; } maintenance_t; const char *__function_name = "update_maintenance_hosts"; int i; zbx_uint64_t *ids = NULL, hostid; int ids_alloc = 0, ids_num = 0; DB_RESULT result; DB_ROW row; char *sql = NULL; size_t sql_alloc = ZBX_KIBIBYTE, sql_offset; maintenance_t *maintenances = NULL, *m; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); sql = zbx_malloc(sql, sql_alloc); DBbegin(); for (i = 0; i < hm_count; i++) { if (SUCCEED == uint64_array_exists(ids, ids_num, hm[i].hostid)) continue; if (hm[i].host_maintenanceid != hm[i].maintenanceid || HOST_MAINTENANCE_STATUS_ON != hm[i].host_maintenance_status || hm[i].host_maintenance_type != hm[i].maintenance_type || 0 == hm[i].host_maintenance_from) { zabbix_log(LOG_LEVEL_WARNING, "putting host [%s] into maintenance (with%s data collection)", hm[i].host, MAINTENANCE_TYPE_NORMAL == hm[i].maintenance_type ? "" : "out"); sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update hosts" " set maintenanceid=" ZBX_FS_UI64 "," "maintenance_status=%d," "maintenance_type=%d", hm[i].maintenanceid, HOST_MAINTENANCE_STATUS_ON, hm[i].maintenance_type); if (0 == hm[i].host_maintenance_from) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, ",maintenance_from=%d", hm[i].maintenance_from); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where hostid=" ZBX_FS_UI64, hm[i].hostid); DBexecute("%s", sql); DCconfig_set_maintenance(&hm[i].hostid, 1, HOST_MAINTENANCE_STATUS_ON, hm[i].maintenance_type, hm[i].maintenance_from); } uint64_array_add(&ids, &ids_alloc, &ids_num, hm[i].hostid, 4); } sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select hostid,host,maintenance_type,maintenance_from" " from hosts" " where status=%d" " and flags<>%d" " and maintenance_status=%d", HOST_STATUS_MONITORED, ZBX_FLAG_DISCOVERY_PROTOTYPE, HOST_MAINTENANCE_STATUS_ON); if (NULL != ids && 0 != ids_num) { zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " and not"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", ids, ids_num); } result = DBselect("%s", sql); ids_num = 0; while (NULL != (row = DBfetch(result))) { zabbix_log(LOG_LEVEL_WARNING, "taking host [%s] out of maintenance", row[1]); ZBX_STR2UINT64(hostid, row[0]); uint64_array_add(&ids, &ids_alloc, &ids_num, hostid, 4); if (MAINTENANCE_TYPE_NORMAL != atoi(row[2])) continue; m = zbx_malloc(NULL, sizeof(maintenance_t)); m->hostid = hostid; m->maintenance_from = atoi(row[3]); m->next = maintenances; maintenances = m; } DBfree_result(result); sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update hosts" " set maintenanceid=null," "maintenance_status=%d," "maintenance_type=0," "maintenance_from=0" " where", HOST_MAINTENANCE_STATUS_OFF); if (NULL != ids && 0 != ids_num) { DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", ids, ids_num); DBexecute("%s", sql); DCconfig_set_maintenance(ids, ids_num, HOST_MAINTENANCE_STATUS_OFF, 0, 0); } DBcommit(); zbx_free(sql); zbx_free(ids); for (m = maintenances; NULL != m; m = m->next) generate_events(m->hostid, m->maintenance_from, now); for (m = maintenances; NULL != m; m = maintenances) { maintenances = m->next; zbx_free(m); } zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
int DBcheck_version(void) { const char *__function_name = "DBcheck_version"; const char *dbversion_table_name = "dbversion"; int db_mandatory, db_optional, required, ret = FAIL, i; zbx_db_version_t *dbversion; zbx_dbpatch_t *patches; #ifndef HAVE_SQLITE3 int total = 0, current = 0, completed, last_completed = -1, optional_num = 0; #endif zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); required = ZBX_FIRST_DB_VERSION; /* find out the required version number by getting the last mandatory version */ /* of the last version patch array */ for (dbversion = dbversions; NULL != dbversion->patches; dbversion++) ; patches = (--dbversion)->patches; for (i = 0; 0 != patches[i].version; i++) { if (0 != patches[i].mandatory) required = patches[i].version; } DBconnect(ZBX_DB_CONNECT_NORMAL); if (SUCCEED != DBtable_exists(dbversion_table_name)) { #ifndef HAVE_SQLITE3 zabbix_log(LOG_LEVEL_DEBUG, "%s() \"%s\" does not exist", __function_name, dbversion_table_name); if (SUCCEED != DBfield_exists("config", "server_check_interval")) { zabbix_log(LOG_LEVEL_CRIT, "Cannot upgrade database: the database must" " correspond to version 2.0 or later. Exiting ..."); goto out; } if (SUCCEED != DBcreate_dbversion_table()) goto out; #else zabbix_log(LOG_LEVEL_CRIT, "The %s does not match Zabbix database." " Current database version (mandatory/optional): UNKNOWN." " Required mandatory version: %08d.", ZBX_DAEMON_TYPE_SERVER == daemon_type ? "server" : "proxy", required); zabbix_log(LOG_LEVEL_CRIT, "Zabbix does not support SQLite3 database upgrade."); goto out; #endif } DBget_version(&db_mandatory, &db_optional); #ifndef HAVE_SQLITE3 for (dbversion = dbversions; NULL != (patches = dbversion->patches); dbversion++) { for (i = 0; 0 != patches[i].version; i++) { if (0 != patches[i].mandatory) optional_num = 0; else optional_num++; if (db_optional < patches[i].version) total++; } } if (required < db_mandatory) #else if (required != db_mandatory) #endif { zabbix_log(LOG_LEVEL_CRIT, "The %s does not match Zabbix database." " Current database version (mandatory/optional): %08d/%08d." " Required mandatory version: %08d.", ZBX_DAEMON_TYPE_SERVER == daemon_type ? "server" : "proxy", db_mandatory, db_optional, required); #ifdef HAVE_SQLITE3 if (required > db_mandatory) zabbix_log(LOG_LEVEL_CRIT, "Zabbix does not support SQLite3 database upgrade."); #endif goto out; } zabbix_log(LOG_LEVEL_INFORMATION, "current database version (mandatory/optional): %08d/%08d", db_mandatory, db_optional); zabbix_log(LOG_LEVEL_INFORMATION, "required mandatory version: %08d", required); ret = SUCCEED; #ifndef HAVE_SQLITE3 if (0 == total) goto out; if (0 != optional_num) zabbix_log(LOG_LEVEL_INFORMATION, "optional patches were found"); zabbix_log(LOG_LEVEL_WARNING, "starting automatic database upgrade"); for (dbversion = dbversions; NULL != dbversion->patches; dbversion++) { zbx_dbpatch_t *patches = dbversion->patches; for (i = 0; 0 != patches[i].version; i++) { if (db_optional >= patches[i].version) continue; DBbegin(); /* skipping the duplicated patches */ if ((0 != patches[i].duplicates && patches[i].duplicates <= db_optional) || SUCCEED == (ret = patches[i].function())) { ret = DBset_version(patches[i].version, patches[i].mandatory); } DBend(ret); if (SUCCEED != ret) break; current++; completed = (int)(100.0 * current / total); if (last_completed != completed) { zabbix_log(LOG_LEVEL_WARNING, "completed %d%% of database upgrade", completed); last_completed = completed; } } if (SUCCEED != ret) break; } if (SUCCEED == ret) zabbix_log(LOG_LEVEL_WARNING, "database upgrade fully completed"); else zabbix_log(LOG_LEVEL_CRIT, "database upgrade failed"); #endif /* not HAVE_SQLITE3 */ out: DBclose(); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: node_history * * * * Purpose: process new history received from a slave node * * * * Parameters: * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ int node_history(char *data, size_t datalen) { const char *r; char *newline = NULL; char *pos; int sender_nodeid = 0, nodeid = 0, firstline = 1, events = 0, history = 0, acknowledges = 0; const ZBX_TABLE *table_sync = NULL, *table = NULL; int res = SUCCEED; char *sql1 = NULL, *sql2 = NULL, *sql3 = NULL; size_t sql1_alloc, sql2_alloc, sql3_alloc; size_t sql1_offset, sql2_offset, sql3_offset; zbx_vector_uint64_t ack_eventids; assert(data); zabbix_log(LOG_LEVEL_DEBUG, "In node_history()"); buffer_alloc = 4 * ZBX_KIBIBYTE; sql1_alloc = 32 * ZBX_KIBIBYTE; sql2_alloc = 32 * ZBX_KIBIBYTE; sql3_alloc = 32 * ZBX_KIBIBYTE; tmp_alloc = 4 * ZBX_KIBIBYTE; buffer = zbx_malloc(buffer, buffer_alloc); sql1 = zbx_malloc(sql1, sql1_alloc); sql2 = zbx_malloc(sql2, sql2_alloc); sql3 = zbx_malloc(sql3, sql3_alloc); tmp = zbx_malloc(tmp, tmp_alloc); zbx_vector_uint64_create(&ack_eventids); DBbegin(); for (r = data; *r != '\0' && res == SUCCEED;) { if (NULL != (newline = strchr(r, '\n'))) *newline = '\0'; if (1 == firstline) { zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); /* constant 'History' */ zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); /* sender_nodeid */ sender_nodeid=atoi(buffer); zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); /* nodeid */ nodeid=atoi(buffer); zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); /* tablename */ if (FAIL == is_direct_slave_node(sender_nodeid)) { zabbix_log(LOG_LEVEL_ERR, "NODE %d: Received data from node %d" " that is not a direct slave node", CONFIG_NODEID, sender_nodeid); res = FAIL; } if (FAIL == is_slave_node(CONFIG_NODEID, nodeid)) { zabbix_log(LOG_LEVEL_ERR, "NODE %d: Received history for unknown slave node %d", CONFIG_NODEID, nodeid); res = FAIL; } table = DBget_table(buffer); if (NULL != table && 0 == (table->flags & (ZBX_HISTORY | ZBX_HISTORY_SYNC))) table = NULL; if (NULL != table && 0 != (table->flags & ZBX_HISTORY_SYNC)) { table_sync = table; if (NULL != (pos = strstr(buffer, "_sync"))) { *pos = '\0'; table = DBget_table(buffer); } } if (NULL == table) { zabbix_log(LOG_LEVEL_ERR, "NODE %d: Invalid received data: unknown tablename \"%s\"", CONFIG_NODEID, buffer); res = FAIL; } else { if (0 == strcmp(table->table, "events")) events = 1; if (0 == strncmp(table->table, "history", 7)) history = 1; if (0 == strcmp(table->table, "acknowledges")) acknowledges = 1; } if (NULL != newline) { zabbix_log(LOG_LEVEL_WARNING, "NODE %d: Received %s from node %d for node %d datalen " ZBX_FS_SIZE_T, CONFIG_NODEID, buffer, sender_nodeid, nodeid, (zbx_fs_size_t)datalen); } firstline = 0; sql1_offset = 0; sql2_offset = 0; sql3_offset = 0; } else if (NULL != table) { if (events) { res = process_record_event(sender_nodeid, nodeid, table, r); } else { res = process_record(&sql1, &sql1_alloc, &sql1_offset, sender_nodeid, nodeid, table, r, newline ? 0 : 1, acknowledges, &ack_eventids); if (SUCCEED == res && 0 != history) { res = process_items(&sql2, &sql2_alloc, &sql2_offset, sender_nodeid, nodeid, table, r, newline ? 0 : 1); } if (SUCCEED == res && NULL != table_sync && 0 != CONFIG_MASTER_NODEID) { res = process_record(&sql3, &sql3_alloc, &sql3_offset, sender_nodeid, nodeid, table_sync, r, newline ? 0 : 1, 0, NULL); } } } if (newline != NULL) { *newline = '\n'; r = newline + 1; } else break; } if (SUCCEED == res) DBcommit(); else DBrollback(); zbx_vector_uint64_destroy(&ack_eventids); zbx_free(tmp); zbx_free(sql1); zbx_free(sql2); zbx_free(sql3); zbx_free(buffer); return res; }
/****************************************************************************** * * * Function: db_update_event_suppress_data * * * * Purpose: create/update event suppress data to reflect latest maintenance * * changes in cache * * * * Parameters: suppressed_num - [OUT] the number of suppressed events * * * ******************************************************************************/ static void db_update_event_suppress_data(int *suppressed_num) { zbx_vector_ptr_t event_queries, event_data; *suppressed_num = 0; zbx_vector_ptr_create(&event_queries); zbx_vector_ptr_create(&event_data); db_get_query_events(&event_queries, &event_data); if (0 != event_queries.values_num) { zbx_db_insert_t db_insert; char *sql = NULL; size_t sql_alloc = 0, sql_offset = 0; int i, j, k; zbx_event_suppress_query_t *query; zbx_event_suppress_data_t *data; zbx_vector_uint64_pair_t del_event_maintenances; zbx_vector_uint64_t maintenanceids; zbx_uint64_pair_t pair; zbx_vector_uint64_create(&maintenanceids); zbx_vector_uint64_pair_create(&del_event_maintenances); db_get_query_functions(&event_queries); db_get_query_tags(&event_queries); zbx_dc_get_running_maintenanceids(&maintenanceids); DBbegin(); if (0 != maintenanceids.values_num && SUCCEED == zbx_db_lock_maintenanceids(&maintenanceids)) zbx_dc_get_event_maintenances(&event_queries, &maintenanceids); zbx_db_insert_prepare(&db_insert, "event_suppress", "event_suppressid", "eventid", "maintenanceid", "suppress_until", NULL); DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset); for (i = 0; i < event_queries.values_num; i++) { query = (zbx_event_suppress_query_t *)event_queries.values[i]; zbx_vector_uint64_pair_sort(&query->maintenances, ZBX_DEFAULT_UINT64_COMPARE_FUNC); k = 0; if (FAIL != (j = zbx_vector_ptr_bsearch(&event_data, &query->eventid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC))) { data = (zbx_event_suppress_data_t *)event_data.values[j]; zbx_vector_uint64_pair_sort(&data->maintenances, ZBX_DEFAULT_UINT64_COMPARE_FUNC); j = 0; while (j < data->maintenances.values_num && k < query->maintenances.values_num) { if (data->maintenances.values[j].first < query->maintenances.values[k].first) { pair.first = query->eventid; pair.second = data->maintenances.values[j].first; zbx_vector_uint64_pair_append(&del_event_maintenances, pair); j++; continue; } if (data->maintenances.values[j].first > query->maintenances.values[k].first) { if (0 == query->r_eventid) { zbx_db_insert_add_values(&db_insert, __UINT64_C(0), query->eventid, query->maintenances.values[k].first, (int)query->maintenances.values[k].second); (*suppressed_num)++; } k++; continue; } if (data->maintenances.values[j].second != query->maintenances.values[k].second) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update event_suppress" " set suppress_until=%d" " where eventid=" ZBX_FS_UI64 " and maintenanceid=" ZBX_FS_UI64 ";\n", (int)query->maintenances.values[k].second, query->eventid, query->maintenances.values[k].first); if (FAIL == DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset)) goto cleanup; } j++; k++; } for (;j < data->maintenances.values_num; j++) { pair.first = query->eventid; pair.second = data->maintenances.values[j].first; zbx_vector_uint64_pair_append(&del_event_maintenances, pair); } } if (0 == query->r_eventid) { for (;k < query->maintenances.values_num; k++) { zbx_db_insert_add_values(&db_insert, __UINT64_C(0), query->eventid, query->maintenances.values[k].first, (int)query->maintenances.values[k].second); (*suppressed_num)++; } } } for (i = 0; i < del_event_maintenances.values_num; i++) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "delete from event_suppress" " where eventid=" ZBX_FS_UI64 " and maintenanceid=" ZBX_FS_UI64 ";\n", del_event_maintenances.values[i].first, del_event_maintenances.values[i].second); if (FAIL == DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset)) goto cleanup; } DBend_multiple_update(&sql, &sql_alloc, &sql_offset); if (16 < sql_offset) { if (ZBX_DB_OK > DBexecute("%s", sql)) goto cleanup; } zbx_db_insert_autoincrement(&db_insert, "event_suppressid"); zbx_db_insert_execute(&db_insert); cleanup: DBcommit(); zbx_db_insert_clean(&db_insert); zbx_free(sql); zbx_vector_uint64_pair_destroy(&del_event_maintenances); zbx_vector_uint64_destroy(&maintenanceids); } zbx_vector_ptr_clear_ext(&event_data, (zbx_clean_func_t)event_suppress_data_free); zbx_vector_ptr_destroy(&event_data); zbx_vector_ptr_clear_ext(&event_queries, (zbx_clean_func_t)zbx_event_suppress_query_free); zbx_vector_ptr_destroy(&event_queries); }
static void DBupdate_lastsize() { DBbegin(); DBexecute("update globalvars set snmp_lastsize=%d", trap_lastsize); DBcommit(); }
/****************************************************************************** * * * Function: DCflush_nextchecks * * * * Purpose: add item nextcheck to the array * * * * Parameters: * * * * Return value: * * * * Author: Aleksander Vladishev * * * * Comments: * * * ******************************************************************************/ void DCflush_nextchecks() { int i, sql_offset = 0, sql_allocated = 1024; char *sql = NULL; time_t last_clock = -1; zbx_uint64_t last_itemid = 0; char *error_esc; zabbix_log(LOG_LEVEL_DEBUG, "In DCflush_nextchecks()"); if (nextcheck_num == 0) return; sql = zbx_malloc(sql, sql_allocated); #ifdef HAVE_ORACLE zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "begin\n"); #endif for (i = 0; i < nextcheck_num; i++) { if (NULL != nextchecks[i].error_msg) continue; if (last_clock != nextchecks[i].clock) { if (last_clock != -1) { sql_offset--; zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 4, ");\n"); } if (last_itemid > nextchecks[i].itemid) { #ifdef HAVE_ORACLE zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "end;\n"); #endif DBbegin(); DBexecute("%s", sql); DBcommit(); sql_offset = 0; #ifdef HAVE_ORACLE zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "begin\n"); #endif } zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 64, "update items set nextcheck=%d where itemid in (", (int)nextchecks[i].clock); last_clock = nextchecks[i].clock; } zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 32, ZBX_FS_UI64 ",", nextchecks[i].itemid); last_itemid = nextchecks[i].itemid; } if (sql_offset > 8) { sql_offset--; zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 4, ");\n"); } for (i = 0; i < nextcheck_num; i++) { if (NULL == nextchecks[i].error_msg) /* not supported items */ continue; if (last_itemid > nextchecks[i].itemid) { #ifdef HAVE_ORACLE zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "end;\n"); #endif DBbegin(); DBexecute("%s", sql); DBcommit(); sql_offset = 0; #ifdef HAVE_ORACLE zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "begin\n"); #endif } error_esc = DBdyn_escape_string_len(nextchecks[i].error_msg, ITEM_ERROR_LEN); zbx_free(nextchecks[i].error_msg); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128 + strlen(error_esc), "update items set status=%d,lastclock=%d,nextcheck=%d,error='%s'" " where itemid=" ZBX_FS_UI64 ";\n", ITEM_STATUS_NOTSUPPORTED, (int)nextchecks[i].clock, (int)(nextchecks[i].clock + CONFIG_REFRESH_UNSUPPORTED), error_esc, nextchecks[i].itemid); last_itemid = nextchecks[i].itemid; zbx_free(error_esc); } #ifdef HAVE_ORACLE zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "end;\n"); #endif if (sql_offset > 16) { DBbegin(); DBexecute("%s", sql); DBcommit(); } zbx_free(sql); }
/****************************************************************************** * * * Function: db_remove_expired_event_suppress_data * * * * Purpose: remove expired event_suppress records * * * ******************************************************************************/ static void db_remove_expired_event_suppress_data(int now) { DBbegin(); DBexecute("delete from event_suppress where suppress_until<%d", now); DBcommit(); }
/****************************************************************************** * * * Function: DCflush_nextchecks * * * * Purpose: add item nextcheck to the array * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev, Dmitry Borovikov * * * * Comments: * * * ******************************************************************************/ void DCflush_nextchecks() { const char *__function_name = "DCflush_nextchecks"; int i, sql_offset = 0, sql_allocated = 4096; char *sql = NULL; DB_RESULT result; DB_ROW row; zbx_uint64_t triggerid; zbx_uint64_t itemid; zbx_uint64_t events_maxid = 0; char *error_msg_esc = NULL; char *sql_select = NULL; int sql_select_offset = 0, sql_select_allocated = 512; /* a crutch for the function `DBadd_condition_alloc' */ zbx_uint64_t *ids = NULL; int ids_allocated = 0, ids_num = 0; zbx_uint64_t *triggerids = NULL; int triggerids_allocated = 0, triggerids_num = 0; struct event_objectid_clock *events = NULL; int events_num = 0, events_allocated = 32; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (nextcheck_num == 0) return; sql = zbx_malloc(sql, sql_allocated); DBbegin(); #ifdef HAVE_ORACLE zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "begin\n"); #endif /* dealing with items */ for (i = 0; i < nextcheck_num; i++) { if (NULL == nextchecks[i].error_msg) continue; uint64_array_add(&ids, &ids_allocated, &ids_num, nextchecks[i].itemid, 64); error_msg_esc = DBdyn_escape_string_len(nextchecks[i].error_msg, ITEM_ERROR_LEN); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128 + strlen(error_msg_esc), "update items set status=%d,lastclock=%d,error='%s' where itemid=" ZBX_FS_UI64 ";\n", ITEM_STATUS_NOTSUPPORTED, (int)nextchecks[i].now, error_msg_esc, nextchecks[i].itemid); zbx_free(error_msg_esc); DBexecute_overflowed_sql(&sql, &sql_allocated, &sql_offset); } /* dealing with notsupported items */ if (ids_num > 0) { sql_select = zbx_malloc(sql_select, sql_select_allocated); events = zbx_malloc(events, events_allocated * sizeof(struct event_objectid_clock)); /* preparing triggers */ zbx_snprintf_alloc(&sql_select, &sql_select_allocated, &sql_select_offset, 256, "select t.triggerid,i.itemid" " from triggers t,functions f,items i" " where t.triggerid=f.triggerid" " and f.itemid=i.itemid" " and t.status in (%d)" " and t.value not in (%d)" " and", TRIGGER_STATUS_ENABLED, TRIGGER_VALUE_UNKNOWN); DBadd_condition_alloc(&sql_select, &sql_select_allocated, &sql_select_offset, "i.itemid", ids, ids_num); result = DBselect("%s", sql_select); zbx_free(sql_select); /* processing triggers */ while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(triggerid, row[0]); ZBX_STR2UINT64(itemid, row[1]); /* do not generate multiple unknown events for a trigger */ if (SUCCEED == uint64_array_exists(triggerids, triggerids_num, triggerid)) continue; uint64_array_add(&triggerids, &triggerids_allocated, &triggerids_num, triggerid, 64); /* index `i' will surely contain necessary itemid */ i = get_nearestindex(nextchecks, sizeof(ZBX_DC_NEXTCHECK), nextcheck_num, itemid); if (i == nextcheck_num || nextchecks[i].itemid != itemid) { THIS_SHOULD_NEVER_HAPPEN; continue; } error_msg_esc = DBdyn_escape_string_len(nextchecks[i].error_msg, TRIGGER_ERROR_LEN); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128 + strlen(error_msg_esc), "update triggers set value=%d,lastchange=%d,error='%s' where triggerid=" ZBX_FS_UI64";\n", TRIGGER_VALUE_UNKNOWN, nextchecks[i].now, error_msg_esc, triggerid); zbx_free(error_msg_esc); if (events_num == events_allocated) { events_allocated += 32; events = zbx_realloc(events, events_allocated * sizeof(struct event_objectid_clock)); } events[events_num].objectid = triggerid; events[events_num].clock = nextchecks[i].now; events_num++; DBexecute_overflowed_sql(&sql, &sql_allocated, &sql_offset); } DBfree_result(result); /* dealing with events */ for (i = 0; i < events_num; i++) { events_maxid = DBget_maxid("events"); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 256, "insert into events (eventid,source,object,objectid,clock,value) " "values (" ZBX_FS_UI64 ",%d,%d," ZBX_FS_UI64 ",%d,%d);\n", events_maxid, EVENT_SOURCE_TRIGGERS, EVENT_OBJECT_TRIGGER, events[i].objectid, events[i].clock, TRIGGER_VALUE_UNKNOWN); DBexecute_overflowed_sql(&sql, &sql_allocated, &sql_offset); } zbx_free(events); } #ifdef HAVE_ORACLE zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "end;\n"); #endif if (sql_offset > 16) /* In ORACLE always present begin..end; */ DBexecute("%s", sql); zbx_free(sql); zbx_free(ids); zbx_free(triggerids); DCrelease_nextchecks(); DBcommit(); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: lld_process_discovery_rule * * * * Purpose: add or update items, triggers and graphs for discovery item * * * * Parameters: lld_ruleid - [IN] discovery item identificator from database * * value - [IN] received value from agent * * * ******************************************************************************/ void lld_process_discovery_rule(zbx_uint64_t lld_ruleid, char *value, const zbx_timespec_t *ts) { const char *__function_name = "lld_process_discovery_rule"; DB_RESULT result; DB_ROW row; zbx_uint64_t hostid = 0; char *discovery_key = NULL, *error = NULL, *db_error = NULL, *error_esc; unsigned char state = 0; unsigned short lifetime; zbx_vector_ptr_t lld_rows; char *sql = NULL; size_t sql_alloc = 128, sql_offset = 0; const char *sql_start = "update items set ", *sql_continue = ","; lld_filter_t filter; time_t now; zabbix_log(LOG_LEVEL_DEBUG, "In %s() itemid:" ZBX_FS_UI64, __function_name, lld_ruleid); zbx_vector_ptr_create(&lld_rows); lld_filter_init(&filter); sql = zbx_malloc(sql, sql_alloc); result = DBselect( "select hostid,key_,state,evaltype,formula,error,lifetime" " from items" " where itemid=" ZBX_FS_UI64, lld_ruleid); if (NULL != (row = DBfetch(result))) { char *lifetime_str; ZBX_STR2UINT64(hostid, row[0]); discovery_key = zbx_strdup(discovery_key, row[1]); state = (unsigned char)atoi(row[2]); filter.evaltype = atoi(row[3]); filter.expression = zbx_strdup(NULL, row[4]); db_error = zbx_strdup(db_error, row[5]); lifetime_str = zbx_strdup(NULL, row[6]); substitute_simple_macros(NULL, NULL, NULL, NULL, &hostid, NULL, NULL, NULL, &lifetime_str, MACRO_TYPE_COMMON, NULL, 0); if (SUCCEED != is_ushort(lifetime_str, &lifetime)) { zabbix_log(LOG_LEVEL_WARNING, "cannot process lost resources for the discovery rule \"%s:%s\":" " \"%s\" is not a valid value", zbx_host_string(hostid), discovery_key, lifetime_str); lifetime = 3650; /* max value for the field */ } zbx_free(lifetime_str); } else zabbix_log(LOG_LEVEL_WARNING, "invalid discovery rule ID [" ZBX_FS_UI64 "]", lld_ruleid); DBfree_result(result); if (0 == hostid) goto clean; if (SUCCEED != lld_filter_load(&filter, lld_ruleid, &error)) goto error; if (SUCCEED != lld_rows_get(value, &filter, &lld_rows, &error)) goto error; error = zbx_strdup(error, ""); now = time(NULL); lld_update_items(hostid, lld_ruleid, &lld_rows, &error, lifetime, now); lld_update_triggers(hostid, lld_ruleid, &lld_rows, &error); lld_update_graphs(hostid, lld_ruleid, &lld_rows, &error); lld_update_hosts(lld_ruleid, &lld_rows, &error, lifetime, now); if (ITEM_STATE_NOTSUPPORTED == state) { zabbix_log(LOG_LEVEL_WARNING, "discovery rule [" ZBX_FS_UI64 "][%s] became supported", lld_ruleid, zbx_host_key_string(lld_ruleid)); add_event(EVENT_SOURCE_INTERNAL, EVENT_OBJECT_LLDRULE, lld_ruleid, ts, ITEM_STATE_NORMAL, NULL, NULL, NULL, 0, 0, NULL, 0, NULL); process_events(); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sstate=%d", sql_start, ITEM_STATE_NORMAL); sql_start = sql_continue; } error: if (NULL != error && 0 != strcmp(error, db_error)) { error_esc = DBdyn_escape_string_len(error, ITEM_ERROR_LEN); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%serror='%s'", sql_start, error_esc); sql_start = sql_continue; zbx_free(error_esc); } if (sql_start == sql_continue) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where itemid=" ZBX_FS_UI64, lld_ruleid); DBbegin(); DBexecute("%s", sql); DBcommit(); } clean: zbx_free(error); zbx_free(db_error); zbx_free(discovery_key); zbx_free(sql); lld_filter_clean(&filter); zbx_vector_ptr_clear_ext(&lld_rows, (zbx_clean_func_t)lld_row_free); zbx_vector_ptr_destroy(&lld_rows); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: process_proxy * * * * Purpose: retrieve values of metrics from monitored hosts * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static int process_proxy(void) { const char *__function_name = "process_proxy"; DC_PROXY proxy; int num, i, ret; struct zbx_json j; struct zbx_json_parse jp, jp_data; zbx_socket_t s; char *answer = NULL, *port = NULL; time_t now; unsigned char update_nextcheck; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (0 == (num = DCconfig_get_proxypoller_hosts(&proxy, 1))) goto exit; now = time(NULL); zbx_json_init(&j, 512 * 1024); for (i = 0; i < num; i++) { update_nextcheck = 0; if (proxy.proxy_config_nextcheck <= now) update_nextcheck |= 0x01; if (proxy.proxy_data_nextcheck <= now) update_nextcheck |= 0x02; proxy.addr = proxy.addr_orig; port = zbx_strdup(port, proxy.port_orig); substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &port, MACRO_TYPE_COMMON, NULL, 0); if (FAIL == is_ushort(port, &proxy.port)) { zabbix_log(LOG_LEVEL_ERR, "invalid proxy \"%s\" port: \"%s\"", proxy.host, port); goto network_error; } if (proxy.proxy_config_nextcheck <= now) { char *error = NULL; zbx_json_clean(&j); zbx_json_addstring(&j, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_PROXY_CONFIG, ZBX_JSON_TYPE_STRING); zbx_json_addobject(&j, ZBX_PROTO_TAG_DATA); if (SUCCEED != (ret = get_proxyconfig_data(proxy.hostid, &j, &error))) { zabbix_log(LOG_LEVEL_ERR, "cannot collect configuration data for proxy \"%s\": %s", proxy.host, error); zbx_free(error); goto network_error; } if (SUCCEED == (ret = connect_to_proxy(&proxy, &s, CONFIG_TRAPPER_TIMEOUT))) { zabbix_log(LOG_LEVEL_WARNING, "sending configuration data to proxy \"%s\" at \"%s\"," " datalen " ZBX_FS_SIZE_T, proxy.host, get_ip_by_socket(&s), (zbx_fs_size_t)j.buffer_size); if (SUCCEED == (ret = send_data_to_proxy(&proxy, &s, j.buffer))) { char *error = NULL; if (SUCCEED != (ret = zbx_recv_response(&s, 0, &error))) { zabbix_log(LOG_LEVEL_WARNING, "cannot send configuration data to proxy" " \"%s\" at \"%s\": %s", proxy.host, get_ip_by_socket(&s), error); } zbx_free(error); } disconnect_proxy(&s); } if (SUCCEED != ret) goto network_error; } if (proxy.proxy_data_nextcheck <= now) { if (SUCCEED == get_data_from_proxy(&proxy, ZBX_PROTO_VALUE_HOST_AVAILABILITY, &answer)) { if (SUCCEED == zbx_json_open(answer, &jp)) process_host_availability(&jp); zbx_free(answer); } else goto network_error; retry_history: if (SUCCEED == get_data_from_proxy(&proxy, ZBX_PROTO_VALUE_HISTORY_DATA, &answer)) { if (SUCCEED == zbx_json_open(answer, &jp)) { process_hist_data(NULL, &jp, proxy.hostid, NULL, 0); if (SUCCEED == zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data)) { if (ZBX_MAX_HRECORDS <= zbx_json_count(&jp_data)) { zbx_free(answer); goto retry_history; } } } zbx_free(answer); } else goto network_error; retry_dhistory: if (SUCCEED == get_data_from_proxy(&proxy, ZBX_PROTO_VALUE_DISCOVERY_DATA, &answer)) { if (SUCCEED == zbx_json_open(answer, &jp)) { process_dhis_data(&jp); if (SUCCEED == zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data)) { if (ZBX_MAX_HRECORDS <= zbx_json_count(&jp_data)) { zbx_free(answer); goto retry_dhistory; } } } zbx_free(answer); } else goto network_error; retry_autoreg_host: if (SUCCEED == get_data_from_proxy(&proxy, ZBX_PROTO_VALUE_AUTO_REGISTRATION_DATA, &answer)) { if (SUCCEED == zbx_json_open(answer, &jp)) { process_areg_data(&jp, proxy.hostid); if (SUCCEED == zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data)) { if (ZBX_MAX_HRECORDS <= zbx_json_count(&jp_data)) { zbx_free(answer); goto retry_autoreg_host; } } } zbx_free(answer); } else goto network_error; } DBbegin(); update_proxy_lastaccess(proxy.hostid); DBcommit(); network_error: DCrequeue_proxy(proxy.hostid, update_nextcheck); } zbx_free(port); zbx_json_free(&j); exit: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return num; }
static void activate_host(DC_ITEM *item, int now) { char sql[MAX_STRING_LEN], error_msg[MAX_STRING_LEN]; int offset = 0, *errors_from, *disable_until; unsigned char *available; const char *fld_errors_from, *fld_available, *fld_disable_until, *fld_error, *type; switch (item->type) { case ITEM_TYPE_ZABBIX: errors_from = &item->host.errors_from; available = &item->host.available; disable_until = &item->host.disable_until; fld_errors_from = "errors_from"; fld_available = "available"; fld_disable_until = "disable_until"; fld_error = "error"; type = "Zabbix"; break; case ITEM_TYPE_SNMPv1: case ITEM_TYPE_SNMPv2c: case ITEM_TYPE_SNMPv3: errors_from = &item->host.snmp_errors_from; available = &item->host.snmp_available; disable_until = &item->host.snmp_disable_until; fld_errors_from = "snmp_errors_from"; fld_available = "snmp_available"; fld_disable_until = "snmp_disable_until"; fld_error = "snmp_error"; type = "SNMP"; break; case ITEM_TYPE_IPMI: errors_from = &item->host.ipmi_errors_from; available = &item->host.ipmi_available; disable_until = &item->host.ipmi_disable_until; fld_errors_from = "ipmi_errors_from"; fld_available = "ipmi_available"; fld_disable_until = "ipmi_disable_until"; fld_error = "ipmi_error"; type = "IPMI"; break; default: return; } if (0 == *errors_from && HOST_AVAILABLE_TRUE == *available) return; if (SUCCEED != DCconfig_activate_host(item)) return; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "update hosts set "); if (HOST_AVAILABLE_TRUE != *available) { zbx_snprintf(error_msg, sizeof(error_msg), "Enabling %s host [%s]", type, item->host.host); zabbix_log(LOG_LEVEL_WARNING, "%s", error_msg); zabbix_syslog("%s", error_msg); *available = HOST_AVAILABLE_TRUE; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d,", fld_available, *available); if (available == &item->host.available) update_key_status(item->host.hostid, HOST_STATUS_MONITORED, now); /* 0 */ } *errors_from = 0; *disable_until = 0; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d,%s=%d,%s='' where hostid=" ZBX_FS_UI64, fld_errors_from, *errors_from, fld_disable_until, *disable_until, fld_error, item->host.hostid); DBbegin(); DBexecute("%s", sql); DBcommit(); }
/****************************************************************************** * * * Function : process_history_table_data: * * * * Purpose: process new history data * * * * Parameters: * * * * Return value: * * * * Author: Aleksander Vladishev * * * * Comments: * * * ******************************************************************************/ void process_history_table_data(ZBX_TABLE *table, int master_nodeid, int nodeid) { DB_RESULT result; DB_ROW row; char *data = NULL, *tmp = NULL; int data_allocated = 1024*1024, tmp_allocated = 4096, tmp_offset, data_offset, f, fld, len; int data_found = 0; zbx_uint64_t lastid; zabbix_log( LOG_LEVEL_DEBUG, "In process_history_table_data()"); DBbegin(); if ((table->flags & ZBX_HISTORY) && FAIL == get_history_lastid(master_nodeid, nodeid, table, &lastid)) return; data = zbx_malloc(data, data_allocated); tmp = zbx_malloc(tmp, tmp_allocated); data_offset = 0; zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "History%c%d%c%d%c%s", ZBX_DM_DELIMITER, CONFIG_NODEID, ZBX_DM_DELIMITER, nodeid, ZBX_DM_DELIMITER, table->table); /* Do not send history for current node if CONFIG_NODE_NOHISTORY is set */ /* if ((CONFIG_NODE_NOHISTORY != 0) && (CONFIG_NODEID == nodeid)) goto exit;*/ tmp_offset = 0; if (table->flags & ZBX_HISTORY_SYNC) { zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 128, "select %s,", table->recid); } else { /* ZBX_HISTORY */ zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 16, "select "); } for (f = 0; table->fields[f].name != 0; f++) { if ((table->flags & ZBX_HISTORY_SYNC) && 0 == (table->fields[f].flags & ZBX_HISTORY_SYNC)) continue; zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 128, "%s,", table->fields[f].name); } tmp_offset--; if (table->flags & ZBX_HISTORY_SYNC) { zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 1024, " from %s where nodeid=%d order by %s", table->table, nodeid, table->recid); } else { /* ZBX_HISTORY */ zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 1024, " from %s where %s>"ZBX_FS_UI64 DB_NODE " order by %s", table->table, table->recid, lastid, DBnode(table->recid, nodeid), table->recid); } result = DBselectN(tmp, 10000); while (NULL != (row = DBfetch(result))) { if (table->flags & ZBX_HISTORY_SYNC) { ZBX_STR2UINT64(lastid, row[0]); fld = 1; } else fld = 0; zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "\n"); for (f = 0; table->fields[f].name != 0; f++) { if ((table->flags & ZBX_HISTORY_SYNC) && 0 == (table->fields[f].flags & ZBX_HISTORY_SYNC)) continue; len = (int)strlen(row[fld]); if (table->fields[f].type == ZBX_TYPE_INT || table->fields[f].type == ZBX_TYPE_UINT || table->fields[f].type == ZBX_TYPE_ID || table->fields[f].type == ZBX_TYPE_FLOAT) { zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "%s%c", row[fld], ZBX_DM_DELIMITER); } else { /* ZBX_TYPE_CHAR ZBX_TYPE_BLOB ZBX_TYPE_TEXT */ len = zbx_binary2hex((u_char *)row[fld], len, &tmp, &tmp_allocated); zbx_snprintf_alloc(&data, &data_allocated, &data_offset, len + 8, "%s%c", tmp, ZBX_DM_DELIMITER); } fld++; } data_offset--; data_found = 1; } DBfree_result(result); data[data_offset] = '\0'; if (1 == data_found && SUCCEED == send_to_node(table->table, master_nodeid, nodeid, data)) { if (table->flags & ZBX_HISTORY_SYNC) { DBexecute("delete from %s where nodeid=%d and %s<="ZBX_FS_UI64, table->table, nodeid, table->recid, lastid); } } DBcommit(); zbx_free(tmp); zbx_free(data); }
static void deactivate_host(DC_ITEM *item, int now, const char *error) { char sql[MAX_STRING_LEN], *error_esc, error_msg[MAX_STRING_LEN]; int offset = 0, *errors_from, *disable_until; unsigned char *available; const char *fld_errors_from, *fld_available, *fld_disable_until, *fld_error, *type; switch (item->type) { case ITEM_TYPE_ZABBIX: errors_from = &item->host.errors_from; available = &item->host.available; disable_until = &item->host.disable_until; fld_errors_from = "errors_from"; fld_available = "available"; fld_disable_until = "disable_until"; fld_error = "error"; type = "Zabbix"; break; case ITEM_TYPE_SNMPv1: case ITEM_TYPE_SNMPv2c: case ITEM_TYPE_SNMPv3: errors_from = &item->host.snmp_errors_from; available = &item->host.snmp_available; disable_until = &item->host.snmp_disable_until; fld_errors_from = "snmp_errors_from"; fld_available = "snmp_available"; fld_disable_until = "snmp_disable_until"; fld_error = "snmp_error"; type = "SNMP"; break; case ITEM_TYPE_IPMI: errors_from = &item->host.ipmi_errors_from; available = &item->host.ipmi_available; disable_until = &item->host.ipmi_disable_until; fld_errors_from = "ipmi_errors_from"; fld_available = "ipmi_available"; fld_disable_until = "ipmi_disable_until"; fld_error = "ipmi_error"; type = "IPMI"; break; default: return; } if (SUCCEED != DCconfig_deactivate_host(item, now)) return; DBbegin(); *error_msg = '\0'; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "update hosts set "); /* First error */ if (0 == *errors_from) { zbx_snprintf(error_msg, sizeof(error_msg), "%s Host [%s]: first network error, wait for %d seconds", type, item->host.host, CONFIG_UNREACHABLE_DELAY); *errors_from = now; *disable_until = now + CONFIG_UNREACHABLE_DELAY; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d,", fld_errors_from, *errors_from); } else { if (now - *errors_from <= CONFIG_UNREACHABLE_PERIOD) { /* Still unavailable, but won't change status to UNAVAILABLE yet */ zbx_snprintf(error_msg, sizeof(error_msg), "%s Host [%s]: another network error, wait for %d seconds", type, item->host.host, CONFIG_UNREACHABLE_DELAY); *disable_until = now + CONFIG_UNREACHABLE_DELAY; } else { *disable_until = now + CONFIG_UNAVAILABLE_DELAY; if (HOST_AVAILABLE_FALSE != *available) { zbx_snprintf(error_msg, sizeof(error_msg), "Disabling %s host [%s]", type, item->host.host); *available = HOST_AVAILABLE_FALSE; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d,", fld_available, *available); if (available == &item->host.available) update_key_status(item->host.hostid, HOST_AVAILABLE_FALSE, now); /* 2 */ update_triggers_status_to_unknown(item->host.hostid, item->type, now, "Agent is unavailable."); } error_esc = DBdyn_escape_string_len(error, HOST_ERROR_LEN); offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s='%s',", fld_error, error_esc); zbx_free(error_esc); } } offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d where hostid=" ZBX_FS_UI64, fld_disable_until, *disable_until, item->host.hostid); DBexecute("%s", sql); DBcommit(); if ('\0' != *error_msg) { zabbix_log(LOG_LEVEL_WARNING, "%s", error_msg); zabbix_syslog("%s", error_msg); } }
/****************************************************************************** * * * Function: delete_history * * * * Purpose: remove outdated information from historical table * * * * Parameters: now - current timestamp * * * * Return value: number of rows records * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static int delete_history(const char *table, const char *fieldname, int now) { const char *__function_name = "delete_history"; DB_RESULT result; DB_ROW row; int minclock, records = 0; zbx_uint64_t lastid, maxid; zabbix_log(LOG_LEVEL_DEBUG, "In %s() table:'%s' now:%d", __function_name, table, now); DBbegin(); result = DBselect( "select nextid" " from ids" " where table_name='%s'" " and field_name='%s'", table, fieldname); if (NULL == (row = DBfetch(result))) goto rollback; ZBX_STR2UINT64(lastid, row[0]); DBfree_result(result); result = DBselect("select min(clock) from %s", table); if (NULL == (row = DBfetch(result)) || SUCCEED == DBis_null(row[0])) goto rollback; minclock = atoi(row[0]); DBfree_result(result); result = DBselect("select max(id) from %s", table); if (NULL == (row = DBfetch(result)) || SUCCEED == DBis_null(row[0])) goto rollback; ZBX_STR2UINT64(maxid, row[0]); DBfree_result(result); records = DBexecute( "delete from %s" " where id<" ZBX_FS_UI64 " and (clock<%d" " or (id<=" ZBX_FS_UI64 " and clock<%d))", table, maxid, now - CONFIG_PROXY_OFFLINE_BUFFER * SEC_PER_HOUR, lastid, MIN(now - CONFIG_PROXY_LOCAL_BUFFER * SEC_PER_HOUR, minclock + 4 * CONFIG_HOUSEKEEPING_FREQUENCY * SEC_PER_HOUR)); DBcommit(); return records; rollback: DBfree_result(result); DBrollback(); return 0; }
/****************************************************************************** * * * Function: get_values * * * * Purpose: retrieve values of metrics from monitored hosts * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: always SUCCEED * * * ******************************************************************************/ static int get_values(int now, int *nextcheck) { DB_RESULT result; DB_RESULT result2; DB_ROW row; DB_ROW row2; int delay; int res; DB_ITEM item; AGENT_RESULT agent; int stop = 0, items = 0; static char *unreachable_hosts = NULL; static int unreachable_hosts_alloc = 32; int unreachable_hosts_offset = 0; char istatus[16]; zabbix_log( LOG_LEVEL_DEBUG, "In get_values()"); if (0 != CONFIG_DBSYNCER_FORKS) DCinit_nextchecks(); now = time(NULL); *nextcheck = FAIL; if (NULL == unreachable_hosts) unreachable_hosts = zbx_malloc(unreachable_hosts, unreachable_hosts_alloc); *unreachable_hosts = '\0'; if (0 != CONFIG_REFRESH_UNSUPPORTED) zbx_snprintf(istatus, sizeof(istatus), "%d,%d", ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED); else zbx_snprintf(istatus, sizeof(istatus), "%d", ITEM_STATUS_ACTIVE); switch (poller_type) { case ZBX_POLLER_TYPE_UNREACHABLE: result = DBselect("select h.hostid,min(i.itemid) from hosts h,items i" " where " ZBX_SQL_MOD(h.hostid,%d) "=%d and i.nextcheck<=%d and i.status in (%d)" " and i.type in (%d,%d,%d,%d,%d) and h.status=%d and h.disable_until<=%d" " and h.errors_from!=0 and h.hostid=i.hostid and (h.proxy_hostid=0 or i.type in (%d))" " and i.key_ not in ('%s','%s','%s','%s') and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " group by h.hostid", CONFIG_UNREACHABLE_POLLER_FORKS, poller_num-1, now + POLLER_DELAY, ITEM_STATUS_ACTIVE, ITEM_TYPE_ZABBIX, ITEM_TYPE_SNMPv1, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3, ITEM_TYPE_IPMI, HOST_STATUS_MONITORED, now, ITEM_TYPE_INTERNAL, SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY, HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); break; case ZBX_POLLER_TYPE_IPMI: result = DBselect("select %s where i.nextcheck<=%d and i.status in (%s)" " and i.type in (%d) and h.status=%d and h.disable_until<=%d" " and h.errors_from=0 and h.hostid=i.hostid and (h.proxy_hostid=0 or i.type in (%d))" " and " ZBX_SQL_MOD(h.hostid,%d) "=%d and i.key_ not in ('%s','%s','%s','%s')" " and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " order by i.nextcheck", ZBX_SQL_ITEM_SELECT, now + POLLER_DELAY, istatus, ITEM_TYPE_IPMI, HOST_STATUS_MONITORED, now, ITEM_TYPE_INTERNAL, CONFIG_IPMIPOLLER_FORKS, poller_num-1, SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY, HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); break; default: /* ZBX_POLLER_TYPE_NORMAL */ result = DBselect("select %s where i.nextcheck<=%d and h.hostid=i.hostid and h.status=%d and i.status in (%s)" " and ((h.disable_until<=%d and h.errors_from=0 and i.type in (%d,%d,%d,%d)) or i.type in (%d,%d,%d,%d,%d))" " and (h.proxy_hostid=0 or i.type in (%d))" " and " ZBX_SQL_MOD(i.itemid,%d) "=%d and i.key_ not in ('%s','%s','%s','%s')" " and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " order by i.nextcheck", ZBX_SQL_ITEM_SELECT, now + POLLER_DELAY, HOST_STATUS_MONITORED, istatus, now, ITEM_TYPE_ZABBIX, ITEM_TYPE_SNMPv1, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3, ITEM_TYPE_SIMPLE, ITEM_TYPE_INTERNAL, ITEM_TYPE_AGGREGATE, ITEM_TYPE_EXTERNAL, ITEM_TYPE_DB_MONITOR, ITEM_TYPE_INTERNAL, CONFIG_POLLER_FORKS, poller_num-1, SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY, HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); } /* Do not stop when select is made by poller for unreachable hosts */ while((row=DBfetch(result))&&(stop==0 || poller_type == ZBX_POLLER_TYPE_UNREACHABLE)) { /* This code is just to avoid compilation warining about use of uninitialized result2 */ result2 = result; /* */ /* Poller for unreachable hosts */ if(poller_type == ZBX_POLLER_TYPE_UNREACHABLE) { result2 = DBselect("select %s where h.hostid=i.hostid and h.proxy_hostid=0 and i.itemid=%s" DB_NODE, ZBX_SQL_ITEM_SELECT, row[1], DBnode_local("h.hostid")); row2 = DBfetch(result2); if(!row2) { DBfree_result(result2); continue; } DBget_item_from_db(&item,row2); } else { DBget_item_from_db(&item,row); /* Skip unreachable hosts but do not break the loop. */ if(uint64_in_list(unreachable_hosts,item.hostid) == SUCCEED) { zabbix_log( LOG_LEVEL_DEBUG, "Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]", item.hostid,item.key); continue; } } if (item.nextcheck > time(NULL)) { if (*nextcheck == FAIL || (item.nextcheck != 0 && *nextcheck > item.nextcheck)) *nextcheck = item.nextcheck; if (poller_type == ZBX_POLLER_TYPE_UNREACHABLE) DBfree_result(result2); continue; } init_result(&agent); res = get_value(&item, &agent); now = time(NULL); if (res == SUCCEED) { if (HOST_AVAILABLE_TRUE != item.host_available) { DBbegin(); enable_host(&item, now); stop = 1; DBcommit(); } if (item.host_errors_from != 0) { DBbegin(); DBexecute("update hosts set errors_from=0 where hostid=" ZBX_FS_UI64, item.hostid); stop = 1; DBcommit(); } if (0 == CONFIG_DBSYNCER_FORKS) DBbegin(); switch (zbx_process) { case ZBX_PROCESS_SERVER: process_new_value(&item, &agent, now); break; case ZBX_PROCESS_PROXY: proxy_process_new_value(&item, &agent, now); break; } if (0 == CONFIG_DBSYNCER_FORKS) DBcommit(); if (0 != CONFIG_DBSYNCER_FORKS) DCadd_nextcheck(&item, now, 0, NULL); if (poller_type == ZBX_POLLER_TYPE_NORMAL || poller_type == ZBX_POLLER_TYPE_IPMI) if (*nextcheck == FAIL || (item.nextcheck != 0 && *nextcheck > item.nextcheck)) *nextcheck = item.nextcheck; } else if (res == NOTSUPPORTED || res == AGENT_ERROR) { if (item.status != ITEM_STATUS_NOTSUPPORTED) { zabbix_log(LOG_LEVEL_WARNING, "Parameter [%s] is not supported by agent on host [%s] Old status [%d]", item.key, item.host_name, item.status); zabbix_syslog("Parameter [%s] is not supported by agent on host [%s]", item.key, item.host_name); } if (0 == CONFIG_DBSYNCER_FORKS) { DBbegin(); DBupdate_item_status_to_notsupported(&item, now, agent.msg); DBcommit(); } else DCadd_nextcheck(&item, now, 0, agent.msg); if (poller_type == ZBX_POLLER_TYPE_UNREACHABLE) if (*nextcheck == FAIL || (item.nextcheck != 0 && *nextcheck > item.nextcheck)) *nextcheck = item.nextcheck; if (HOST_AVAILABLE_TRUE != item.host_available) { DBbegin(); enable_host(&item, now); stop = 1; DBcommit(); } } else if (res == NETWORK_ERROR) { DBbegin(); /* First error */ if (item.host_errors_from == 0) { zabbix_log( LOG_LEVEL_WARNING, "Host [%s]: first network error, wait for %d seconds", item.host_name, CONFIG_UNREACHABLE_DELAY); zabbix_syslog("Host [%s]: first network error, wait for %d seconds", item.host_name, CONFIG_UNREACHABLE_DELAY); DBexecute("update hosts set errors_from=%d,disable_until=%d where hostid=" ZBX_FS_UI64, now, now + CONFIG_UNREACHABLE_DELAY, item.hostid); item.host_errors_from = now; delay = MIN(4*item.delay, 300); zabbix_log(LOG_LEVEL_WARNING, "Parameter [%s] will be checked after %d seconds on host [%s]", item.key, delay, item.host_name); DBexecute("update items set nextcheck=%d where itemid=" ZBX_FS_UI64, now + delay, item.itemid); } else { if (now - item.host_errors_from > CONFIG_UNREACHABLE_PERIOD) { disable_host(&item, now, agent.msg); } else { /* Still unavailable, but won't change status to UNAVAILABLE yet */ zabbix_log(LOG_LEVEL_WARNING, "Host [%s]: another network error, wait for %d seconds", item.host_name, CONFIG_UNREACHABLE_DELAY); zabbix_syslog("Host [%s]: another network error, wait for %d seconds", item.host_name, CONFIG_UNREACHABLE_DELAY); DBexecute("update hosts set disable_until=%d where hostid=" ZBX_FS_UI64, now + CONFIG_UNREACHABLE_DELAY, item.hostid); } } DBcommit(); zbx_snprintf_alloc(&unreachable_hosts, &unreachable_hosts_alloc, &unreachable_hosts_offset, 32, "%s" ZBX_FS_UI64, 0 == unreachable_hosts_offset ? "" : ",", item.hostid); } else { zabbix_log(LOG_LEVEL_CRIT, "Unknown response code returned."); assert(0==1); } items++; /* Poller for unreachable hosts */ if (poller_type == ZBX_POLLER_TYPE_UNREACHABLE) { /* We cannot freeit earlier because items has references to the structure */ DBfree_result(result2); } free_result(&agent); } DBfree_result(result); if (0 != CONFIG_DBSYNCER_FORKS) DCflush_nextchecks(); zabbix_log(LOG_LEVEL_DEBUG, "End get_values()"); return items; }
/****************************************************************************** * * * Function: get_hostid_by_host * * * * Purpose: check for host name and return hostid * * * * Parameters: host - [IN] require size 'HOST_HOST_LEN_MAX' * * * * Return value: SUCCEED - host is found * * FAIL - an error occurred or host not found * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ static int get_hostid_by_host(const char *host, const char *ip, unsigned short port, zbx_uint64_t *hostid, char *error) { const char *__function_name = "get_hostid_by_host"; char *host_esc, dns[INTERFACE_DNS_LEN_MAX]; DB_RESULT result; DB_ROW row; int res = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() host:'%s'", __function_name, host); if (FAIL == zbx_check_hostname(host)) { zbx_snprintf(error, MAX_STRING_LEN, "invalid host name [%s]", host); goto out; } host_esc = DBdyn_escape_string(host); result = DBselect( "select hostid,status" " from hosts" " where host='%s'" " and status in (%d,%d)" " and proxy_hostid is null" DB_NODE, host_esc, HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED, DBnode_local("hostid")); if (NULL != (row = DBfetch(result))) { if (HOST_STATUS_MONITORED == atoi(row[1])) { ZBX_STR2UINT64(*hostid, row[0]); res = SUCCEED; } else zbx_snprintf(error, MAX_STRING_LEN, "host [%s] not monitored", host); } else { zbx_snprintf(error, MAX_STRING_LEN, "host [%s] not found", host); /* remove ::ffff: prefix from IPv4-mapped IPv6 addresses */ if (0 == strncmp("::ffff:", ip, 7) && SUCCEED == is_ip4(ip + 7)) ip += 7; alarm(CONFIG_TIMEOUT); zbx_gethost_by_ip(ip, dns, sizeof(dns)); alarm(0); DBbegin(); if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) { DBregister_host(0, host, ip, dns, port, (int)time(NULL)); } else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY)) { DBproxy_register_host(host, ip, dns, port); } DBcommit(); } DBfree_result(result); zbx_free(host_esc); out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res)); return res; }
/****************************************************************************** * * * Function: lld_triggers_save * * * * Purpose: add or update triggers in database based on discovery rule * * * ******************************************************************************/ static void lld_triggers_save(zbx_uint64_t parent_triggerid, zbx_vector_ptr_t *triggers, unsigned char status, unsigned char type, unsigned char priority, const char *url) { const char *__function_name = "lld_triggers_save"; int i, j, new_triggers = 0, upd_triggers = 0, new_functions = 0; zbx_lld_trigger_t *trigger; zbx_lld_function_t *function; zbx_vector_ptr_t upd_functions; /* the ordered list of functions which will be updated */ zbx_vector_uint64_t del_functionids; zbx_uint64_t triggerid = 0, functionid = 0; unsigned char flags = ZBX_FLAG_LLD_TRIGGER_UNSET; char *sql = NULL, *url_esc = NULL, *function_esc, *parameter_esc; size_t sql_alloc = 8 * ZBX_KIBIBYTE, sql_offset = 0; zbx_db_insert_t db_insert, db_insert_tdiscovery, db_insert_tfunctions; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_ptr_create(&upd_functions); zbx_vector_uint64_create(&del_functionids); for (i = 0; i < triggers->values_num; i++) { trigger = (zbx_lld_trigger_t *)triggers->values[i]; if (0 == (trigger->flags & ZBX_FLAG_LLD_TRIGGER_DISCOVERED)) continue; if (0 == trigger->triggerid) { new_triggers++; } else if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE)) { upd_triggers++; flags |= trigger->flags; } for (j = 0; j < trigger->functions.values_num; j++) { function = (zbx_lld_function_t *)trigger->functions.values[j]; if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_DELETE)) { zbx_vector_uint64_append(&del_functionids, function->functionid); continue; } if (0 == (function->flags & ZBX_FLAG_LLD_FUNCTION_DISCOVERED)) continue; if (0 == function->functionid) new_functions++; else if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_UPDATE)) zbx_vector_ptr_append(&upd_functions, function); } } if (0 == new_triggers && 0 == new_functions && 0 == upd_triggers && 0 == upd_functions.values_num && 0 == del_functionids.values_num) { goto out; } DBbegin(); if (0 != new_triggers) { triggerid = DBget_maxid_num("triggers", new_triggers); zbx_db_insert_prepare(&db_insert, "triggers", "triggerid", "description", "expression", "priority", "status", "comments", "url", "type", "value", "state", "flags", NULL); zbx_db_insert_prepare(&db_insert_tdiscovery, "trigger_discovery", "triggerid", "parent_triggerid", NULL); } if (0 != new_functions) { functionid = DBget_maxid_num("functions", new_functions); zbx_db_insert_prepare(&db_insert_tfunctions, "functions", "functionid", "itemid", "triggerid", "function", "parameter", NULL); } if (0 != upd_triggers || 0 != upd_functions.values_num || 0 != del_functionids.values_num) { sql = zbx_malloc(sql, sql_alloc); DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset); } if (0 != (flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_URL)) url_esc = DBdyn_escape_string(url); for (i = 0; i < triggers->values_num; i++) { char *description_esc, *expression_esc, *comments_esc; trigger = (zbx_lld_trigger_t *)triggers->values[i]; if (0 == (trigger->flags & ZBX_FLAG_LLD_TRIGGER_DISCOVERED)) continue; for (j = 0; j < trigger->functions.values_num; j++) { function = (zbx_lld_function_t *)trigger->functions.values[j]; if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_DELETE)) continue; if (0 == (function->flags & ZBX_FLAG_LLD_FUNCTION_DISCOVERED)) continue; if (0 == function->functionid) { zbx_db_insert_add_values(&db_insert_tfunctions, functionid, function->itemid, (0 == trigger->triggerid ? triggerid : trigger->triggerid), function->function, function->parameter); function->functionid = functionid++; } } if (0 == trigger->triggerid || 0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_EXPRESSION)) lld_expression_create(&trigger->expression, &trigger->functions); if (0 == trigger->triggerid) { zbx_db_insert_add_values(&db_insert, triggerid, trigger->description, trigger->expression, (int)priority, (int)status, trigger->comments, url, (int)type, (int)TRIGGER_VALUE_OK, (int)TRIGGER_STATE_NORMAL, (int)ZBX_FLAG_DISCOVERY_CREATED); zbx_db_insert_add_values(&db_insert_tdiscovery, triggerid, parent_triggerid); trigger->triggerid = triggerid++; } else if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE)) { const char *d = ""; zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update triggers set "); if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_DESCRIPTION)) { description_esc = DBdyn_escape_string(trigger->description); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "description='%s'", description_esc); zbx_free(description_esc); d = ","; } if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_EXPRESSION)) { expression_esc = DBdyn_escape_string(trigger->expression); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sexpression='%s'", d, expression_esc); zbx_free(expression_esc); d = ","; } if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_TYPE)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%stype=%d", d, (int)type); d = ","; } if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_PRIORITY)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%spriority=%d", d, (int)priority); d = ","; } if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_COMMENTS)) { comments_esc = DBdyn_escape_string(trigger->comments); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%scomments='%s'", d, comments_esc); zbx_free(comments_esc); d = ","; } if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_URL)) zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%surl='%s'", d, url_esc); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where triggerid=" ZBX_FS_UI64 ";\n", trigger->triggerid); } } zbx_free(url_esc); zbx_vector_ptr_sort(&upd_functions, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); for (i = 0; i < upd_functions.values_num; i++) { const char *d = ""; function = (zbx_lld_function_t *)upd_functions.values[i]; zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update functions set "); if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_UPDATE_ITEMID)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "itemid=" ZBX_FS_UI64, function->itemid); d = ","; } if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_UPDATE_FUNCTION)) { function_esc = DBdyn_escape_string(function->function); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sfunction='%s'", d, function_esc); zbx_free(function_esc); d = ","; } if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_UPDATE_PARAMETER)) { parameter_esc = DBdyn_escape_string(function->parameter); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sparameter='%s'", d, parameter_esc); zbx_free(parameter_esc); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where functionid=" ZBX_FS_UI64 ";\n", function->functionid); } if (0 != del_functionids.values_num) { zbx_vector_uint64_sort(&del_functionids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from functions where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "functionid", del_functionids.values, del_functionids.values_num); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n"); } if (0 != upd_triggers || 0 != upd_functions.values_num || 0 != del_functionids.values_num) { DBend_multiple_update(&sql, &sql_alloc, &sql_offset); DBexecute("%s", sql); zbx_free(sql); } if (0 != new_triggers) { zbx_db_insert_execute(&db_insert); zbx_db_insert_clean(&db_insert); zbx_db_insert_execute(&db_insert_tdiscovery); zbx_db_insert_clean(&db_insert_tdiscovery); } if (0 != new_functions) { zbx_db_insert_execute(&db_insert_tfunctions); zbx_db_insert_clean(&db_insert_tfunctions); } DBcommit(); out: zbx_vector_uint64_destroy(&del_functionids); zbx_vector_ptr_destroy(&upd_functions); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: change_nodeid * * * * Purpose: convert database data to new node ID * * * * Parameters: old_id - old id, new_id - new node id * * * * Return value: SUCCEED - converted successfully * * FAIL - an error occurred * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ int change_nodeid(int old_id, int new_id) { struct conv_t { const char *rel; int type; }; struct special_conv_t { const char *table_name, *field_name, *type_field_name; struct conv_t convs[32]; }; struct special_conv_t special_convs[]= { {"sysmaps_elements", "elementid", "elementtype", { {"hosts", SYSMAP_ELEMENT_TYPE_HOST}, {"sysmaps", SYSMAP_ELEMENT_TYPE_MAP}, {"triggers", SYSMAP_ELEMENT_TYPE_TRIGGER}, {"groups", SYSMAP_ELEMENT_TYPE_HOST_GROUP}, {"images", SYSMAP_ELEMENT_TYPE_IMAGE}, {NULL} } }, {"events", "objectid", "object", { {"triggers", EVENT_OBJECT_TRIGGER}, {"dhosts", EVENT_OBJECT_DHOST}, {"dservices", EVENT_OBJECT_DSERVICE}, {NULL} } }, {"operations", "objectid", "object", { {"users", OPERATION_OBJECT_USER}, {"usrgrp", OPERATION_OBJECT_GROUP}, {NULL} } }, {"ids", "nextid", NULL, { {NULL} } }, {"node_cksum", "recordid", NULL, { {NULL} } }, {"screens_items", "resourceid", "resourcetype", { {"graphs", SCREEN_RESOURCE_GRAPH}, {"items", SCREEN_RESOURCE_SIMPLE_GRAPH}, {"sysmaps", SCREEN_RESOURCE_MAP}, {"items", SCREEN_RESOURCE_PLAIN_TEXT}, {"groups", SCREEN_RESOURCE_HOSTS_INFO}, {"screens", SCREEN_RESOURCE_SCREEN}, {"groups", SCREEN_RESOURCE_TRIGGERS_OVERVIEW}, {"groups", SCREEN_RESOURCE_DATA_OVERVIEW}, {"groups", SCREEN_RESOURCE_HOSTGROUP_TRIGGERS}, {"hosts", SCREEN_RESOURCE_HOST_TRIGGERS}, {NULL} } }, {"auditlog", "resourceid", "resourcetype", { {"users", AUDIT_RESOURCE_USER}, /* {"", AUDIT_RESOURCE_ZABBIX},*/ {"config", AUDIT_RESOURCE_ZABBIX_CONFIG}, {"media_type", AUDIT_RESOURCE_MEDIA_TYPE}, {"hosts", AUDIT_RESOURCE_HOST}, {"actions", AUDIT_RESOURCE_ACTION}, {"graphs", AUDIT_RESOURCE_GRAPH}, {"graphs_items", AUDIT_RESOURCE_GRAPH_ELEMENT}, /* {"", AUDIT_RESOURCE_ESCALATION}, {"", AUDIT_RESOURCE_ESCALATION_RULE}, {"", AUDIT_RESOURCE_AUTOREGISTRATION},*/ {"usrgrp", AUDIT_RESOURCE_USER_GROUP}, {"applications", AUDIT_RESOURCE_APPLICATION}, {"triggers", AUDIT_RESOURCE_TRIGGER}, {"groups", AUDIT_RESOURCE_HOST_GROUP}, {"items", AUDIT_RESOURCE_ITEM}, {"images", AUDIT_RESOURCE_IMAGE}, {"valuemaps", AUDIT_RESOURCE_VALUE_MAP}, {"services", AUDIT_RESOURCE_IT_SERVICE}, {"sysmaps", AUDIT_RESOURCE_MAP}, {"screens", AUDIT_RESOURCE_SCREEN}, /* {"nodes", AUDIT_RESOURCE_NODE},*/ /* {"", AUDIT_RESOURCE_SCENARIO},*/ {"drules", AUDIT_RESOURCE_DISCOVERY_RULE}, {"slideshows", AUDIT_RESOURCE_SLIDESHOW}, {"scripts", AUDIT_RESOURCE_SCRIPT}, /* {"", AUDIT_RESOURCE_PROXY},*/ {"maintenances", AUDIT_RESOURCE_MAINTENANCE}, {"regexps", AUDIT_RESOURCE_REGEXP}, {NULL} } }, {NULL} }; struct conv_t condition_convs[]= { {"groups", CONDITION_TYPE_HOST_GROUP}, {"hosts", CONDITION_TYPE_HOST}, {"hosts", CONDITION_TYPE_HOST_TEMPLATE}, {"hosts", CONDITION_TYPE_PROXY}, {"triggers", CONDITION_TYPE_TRIGGER}, {"dchecks", CONDITION_TYPE_DCHECK}, {"drules", CONDITION_TYPE_DRULE}, {NULL}, }; int i, j, s, t; zbx_uint64_t prefix; const ZBX_TABLE *r_table; if(old_id!=0) { printf("Conversion from non-zero node id is not supported.\n"); return FAIL; } if(new_id>999 || new_id<0) { printf("Node ID must be in range of 0-999.\n"); return FAIL; } zabbix_set_log_level(LOG_LEVEL_WARNING); DBconnect(ZBX_DB_CONNECT_EXIT); DBbegin(); printf("Converting tables "); fflush(stdout); for (i = 0; NULL != tables[i].table; i++) { printf("."); fflush(stdout); for (j = 0; NULL != tables[i].fields[j].name; j++) { for (s = 0; NULL != special_convs[s].table_name; s++) if (0 == strcmp(special_convs[s].table_name, tables[i].table) && 0 == strcmp(special_convs[s].field_name, tables[i].fields[j].name)) break; if (NULL != special_convs[s].table_name) { for (t = 0; NULL != special_convs[s].convs[t].rel; t++) { convert_special_field(old_id, new_id, special_convs[s].table_name, special_convs[s].field_name, special_convs[s].type_field_name, special_convs[s].convs[t].rel, special_convs[s].convs[t].type); } continue; } if (tables[i].fields[j].type == ZBX_TYPE_ID) { if (0 == strcmp(tables[i].fields[j].name, tables[i].recid)) /* primary key */ { prefix = (zbx_uint64_t)__UINT64_C(100000000000000)*(zbx_uint64_t)new_id; if (tables[i].flags & ZBX_SYNC) prefix += (zbx_uint64_t)__UINT64_C(100000000000)*(zbx_uint64_t)new_id; } else if (NULL != tables[i].fields[j].rel) /* relations */ { if (NULL == (r_table = DBget_table(tables[i].fields[j].rel))) { printf("%s.%s FAILED\n", tables[i].table, tables[i].fields[j].name); fflush(stdout); continue; } prefix = (zbx_uint64_t)__UINT64_C(100000000000000)*(zbx_uint64_t)new_id; if (r_table->flags & ZBX_SYNC) prefix += (zbx_uint64_t)__UINT64_C(100000000000)*(zbx_uint64_t)new_id; } else if (0 == strcmp("profiles", tables[i].table)) /* special processing for table 'profiles' */ { convert_profiles(old_id, new_id, tables[i].fields[j].name); continue; } else { printf("%s.%s FAILED\n", tables[i].table, tables[i].fields[j].name); fflush(stdout); continue; } DBexecute("update %s set %s=%s+" ZBX_FS_UI64 " where %s>0", tables[i].table, tables[i].fields[j].name, tables[i].fields[j].name, prefix, tables[i].fields[j].name); } } } /* Special processing for trigger expressions */ convert_triggers_expression(old_id, new_id); /* Special processing for condition values */ for (i = 0; NULL != condition_convs[i].rel; i++) convert_condition_values(old_id, new_id, condition_convs[i].rel, condition_convs[i].type); DBexecute("insert into nodes (nodeid,name,ip,nodetype) values (%d,'Local node','127.0.0.1',1)", new_id); DBcommit(); DBclose(); printf(" done.\nConversion completed.\n"); return SUCCEED; }