1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 **/
19
20 #include "lld.h"
21 #include "log.h"
22 #include "db.h"
23
24 /******************************************************************************
25 * *
26 * Function: lld_field_str_rollback *
27 * *
28 * Author: Alexander Vladishev *
29 * *
30 ******************************************************************************/
lld_field_str_rollback(char ** field,char ** field_orig,zbx_uint64_t * flags,zbx_uint64_t flag)31 void lld_field_str_rollback(char **field, char **field_orig, zbx_uint64_t *flags, zbx_uint64_t flag)
32 {
33 if (0 == (*flags & flag))
34 return;
35
36 zbx_free(*field);
37 *field = *field_orig;
38 *field_orig = NULL;
39 *flags &= ~flag;
40 }
41
42 /******************************************************************************
43 * *
44 * Function: lld_field_uint64_rollback *
45 * *
46 * Author: Alexander Vladishev *
47 * *
48 ******************************************************************************/
lld_field_uint64_rollback(zbx_uint64_t * field,zbx_uint64_t * field_orig,zbx_uint64_t * flags,zbx_uint64_t flag)49 void lld_field_uint64_rollback(zbx_uint64_t *field, zbx_uint64_t *field_orig, zbx_uint64_t *flags, zbx_uint64_t flag)
50 {
51 if (0 == (*flags & flag))
52 return;
53
54 *field = *field_orig;
55 *field_orig = 0;
56 *flags &= ~flag;
57 }
58
59 /******************************************************************************
60 * *
61 * Function: lld_end_of_life *
62 * *
63 * Purpose: calculate when to delete lost resources in an overflow-safe way *
64 * *
65 ******************************************************************************/
lld_end_of_life(int lastcheck,int lifetime)66 int lld_end_of_life(int lastcheck, int lifetime)
67 {
68 return ZBX_JAN_2038 - lastcheck > lifetime ? lastcheck + lifetime : ZBX_JAN_2038;
69 }
70
71 /******************************************************************************
72 * *
73 * Function: lld_remove_lost_objects *
74 * *
75 * Purpose: updates lastcheck and ts_delete fields; removes lost resources *
76 * *
77 ******************************************************************************/
lld_remove_lost_objects(const char * table,const char * id_name,const zbx_vector_ptr_t * objects,int lifetime,int lastcheck,delete_ids_f cb,get_object_info_f cb_info)78 void lld_remove_lost_objects(const char *table, const char *id_name, const zbx_vector_ptr_t *objects,
79 int lifetime, int lastcheck, delete_ids_f cb, get_object_info_f cb_info)
80 {
81 char *sql = NULL;
82 size_t sql_alloc = 0, sql_offset = 0;
83 zbx_vector_uint64_t del_ids, lc_ids, ts_ids;
84 zbx_vector_uint64_pair_t discovery_ts;
85 int i;
86
87 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
88
89 if (0 == objects->values_num)
90 goto out;
91
92 zbx_vector_uint64_create(&del_ids);
93 zbx_vector_uint64_create(&lc_ids);
94 zbx_vector_uint64_create(&ts_ids);
95 zbx_vector_uint64_pair_create(&discovery_ts);
96
97 for (i = 0; i < objects->values_num; i++)
98 {
99 zbx_uint64_t id;
100 int discovery_flag, object_lastcheck, object_ts_delete;
101
102 cb_info(objects->values[i], &id, &discovery_flag, &object_lastcheck, &object_ts_delete);
103
104 if (0 == id)
105 continue;
106
107 if (0 == discovery_flag)
108 {
109 int ts_delete = lld_end_of_life(object_lastcheck, lifetime);
110
111 if (lastcheck > ts_delete)
112 {
113 zbx_vector_uint64_append(&del_ids, id);
114 }
115 else if (object_ts_delete != ts_delete)
116 {
117 zbx_uint64_pair_t pair;
118
119 pair.first = id;
120 pair.second = ts_delete;
121 zbx_vector_uint64_pair_append(&discovery_ts, pair);
122 }
123 }
124 else
125 {
126 zbx_vector_uint64_append(&lc_ids, id);
127 if (0 != object_ts_delete)
128 zbx_vector_uint64_append(&ts_ids, id);
129 }
130 }
131
132 if (0 == discovery_ts.values_num && 0 == lc_ids.values_num && 0 == ts_ids.values_num &&
133 0 == del_ids.values_num)
134 {
135 goto clean;
136 }
137
138 /* update discovery table */
139
140 DBbegin();
141
142 DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);
143
144 for (i = 0; i < discovery_ts.values_num; i++)
145 {
146 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
147 "update %s"
148 " set ts_delete=%d"
149 " where %s=" ZBX_FS_UI64 ";\n",
150 table, (int)discovery_ts.values[i].second, id_name, discovery_ts.values[i].first);
151
152 DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
153 }
154
155 if (0 != lc_ids.values_num)
156 {
157 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update %s set lastcheck=%d where",
158 table, lastcheck);
159 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, id_name,
160 lc_ids.values, lc_ids.values_num);
161 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
162
163 DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
164 }
165
166 if (0 != ts_ids.values_num)
167 {
168 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update %s set ts_delete=0 where",
169 table);
170 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, id_name,
171 ts_ids.values, ts_ids.values_num);
172 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
173
174 DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
175 }
176
177 DBend_multiple_update(&sql, &sql_alloc, &sql_offset);
178
179 if (16 < sql_offset) /* in ORACLE always present begin..end; */
180 DBexecute("%s", sql);
181
182 zbx_free(sql);
183
184 /* remove 'lost' objects */
185 if (0 != del_ids.values_num)
186 {
187 zbx_vector_uint64_sort(&del_ids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
188 cb(&del_ids);
189 }
190
191 DBcommit();
192 clean:
193 zbx_vector_uint64_pair_destroy(&discovery_ts);
194 zbx_vector_uint64_destroy(&ts_ids);
195 zbx_vector_uint64_destroy(&lc_ids);
196 zbx_vector_uint64_destroy(&del_ids);
197 out:
198 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
199 }
200