This source file includes following definitions.
- alert_key2param
- alert_key2param_int
- alert_key2param_ms
- set_ev_kv
- alert_envvar2params
- is_target_alert
- exec_alert_list
- lrmd_send_attribute_alert
- lrmd_send_node_alert
- lrmd_send_fencing_alert
- lrmd_send_resource_alert
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <glib.h>
13 #include <unistd.h>
14
15 #include <crm/crm.h>
16 #include <crm/common/xml.h>
17 #include <crm/services.h>
18 #include <crm/common/mainloop.h>
19 #include <crm/common/alerts_internal.h>
20 #include <crm/lrmd_internal.h>
21
22 #include <crm/pengine/status.h>
23 #include <crm/cib.h>
24 #include <crm/lrmd.h>
25
26 static lrmd_key_value_t *
27 alert_key2param(lrmd_key_value_t *head, enum pcmk__alert_keys_e name,
28 const char *value)
29 {
30 if (value == NULL) {
31 value = "";
32 }
33 crm_trace("Setting alert key %s = '%s'", pcmk__alert_keys[name], value);
34 return lrmd_key_value_add(head, pcmk__alert_keys[name], value);
35 }
36
37 static lrmd_key_value_t *
38 alert_key2param_int(lrmd_key_value_t *head, enum pcmk__alert_keys_e name,
39 int value)
40 {
41 char *value_s = pcmk__itoa(value);
42
43 head = alert_key2param(head, name, value_s);
44 free(value_s);
45 return head;
46 }
47
48 static lrmd_key_value_t *
49 alert_key2param_ms(lrmd_key_value_t *head, enum pcmk__alert_keys_e name,
50 guint value)
51 {
52 char *value_s = crm_strdup_printf("%u", value);
53
54 head = alert_key2param(head, name, value_s);
55 free(value_s);
56 return head;
57 }
58
59 static void
60 set_ev_kv(gpointer key, gpointer value, gpointer user_data)
61 {
62 lrmd_key_value_t **head = (lrmd_key_value_t **) user_data;
63
64 if (value) {
65 crm_trace("Setting environment variable %s='%s'",
66 (char*)key, (char*)value);
67 *head = lrmd_key_value_add(*head, key, value);
68 }
69 }
70
71 static lrmd_key_value_t *
72 alert_envvar2params(lrmd_key_value_t *head, const pcmk__alert_t *entry)
73 {
74 if (entry->envvars) {
75 g_hash_table_foreach(entry->envvars, set_ev_kv, &head);
76 }
77 return head;
78 }
79
80
81
82
83
84 static gboolean
85 is_target_alert(char **list, const char *value)
86 {
87 int target_list_num = 0;
88 gboolean rc = FALSE;
89
90 CRM_CHECK(value != NULL, return FALSE);
91
92 if (list == NULL) {
93 return TRUE;
94 }
95
96 target_list_num = g_strv_length(list);
97
98 for (int cnt = 0; cnt < target_list_num; cnt++) {
99 if (strcmp(list[cnt], value) == 0) {
100 rc = TRUE;
101 break;
102 }
103 }
104 return rc;
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121 static int
122 exec_alert_list(lrmd_t *lrmd, const GList *alert_list,
123 enum pcmk__alert_flags kind, const char *attr_name,
124 lrmd_key_value_t *params)
125 {
126 bool any_success = FALSE, any_failure = FALSE;
127 const char *kind_s = pcmk__alert_flag2text(kind);
128 pcmk__time_hr_t *now = NULL;
129 char timestamp_epoch[20];
130 char timestamp_usec[7];
131 time_t epoch = 0;
132
133 params = alert_key2param(params, PCMK__alert_key_kind, kind_s);
134 params = alert_key2param(params, PCMK__alert_key_version,
135 PACEMAKER_VERSION);
136
137 for (const GList *iter = alert_list;
138 iter != NULL; iter = g_list_next(iter)) {
139 const pcmk__alert_t *entry = (pcmk__alert_t *) (iter->data);
140 lrmd_key_value_t *copy_params = NULL;
141 lrmd_key_value_t *head = NULL;
142 int rc;
143
144 if (!pcmk_is_set(entry->flags, kind)) {
145 crm_trace("Filtering unwanted %s alert to %s via %s",
146 kind_s, entry->recipient, entry->id);
147 continue;
148 }
149
150 if ((kind == pcmk__alert_attribute)
151 && !is_target_alert(entry->select_attribute_name, attr_name)) {
152
153 crm_trace("Filtering unwanted attribute '%s' alert to %s via %s",
154 attr_name, entry->recipient, entry->id);
155 continue;
156 }
157
158 if (now == NULL) {
159 now = pcmk__time_hr_now(&epoch);
160 }
161 crm_info("Sending %s alert via %s to %s",
162 kind_s, entry->id, entry->recipient);
163
164
165 for (head = params; head != NULL; head = head->next) {
166 copy_params = lrmd_key_value_add(copy_params, head->key, head->value);
167 }
168
169 copy_params = alert_key2param(copy_params, PCMK__alert_key_recipient,
170 entry->recipient);
171
172 if (now) {
173 char *timestamp = pcmk__time_format_hr(entry->tstamp_format, now);
174
175 if (timestamp) {
176 copy_params = alert_key2param(copy_params,
177 PCMK__alert_key_timestamp,
178 timestamp);
179 free(timestamp);
180 }
181
182 snprintf(timestamp_epoch, sizeof(timestamp_epoch), "%lld",
183 (long long) epoch);
184 copy_params = alert_key2param(copy_params,
185 PCMK__alert_key_timestamp_epoch,
186 timestamp_epoch);
187 snprintf(timestamp_usec, sizeof(timestamp_usec), "%06d", now->useconds);
188 copy_params = alert_key2param(copy_params,
189 PCMK__alert_key_timestamp_usec,
190 timestamp_usec);
191 }
192
193 copy_params = alert_envvar2params(copy_params, entry);
194
195 rc = lrmd->cmds->exec_alert(lrmd, entry->id, entry->path,
196 entry->timeout, copy_params);
197 if (rc < 0) {
198 crm_err("Could not execute alert %s: %s " QB_XS " rc=%d",
199 entry->id, pcmk_strerror(rc), rc);
200 any_failure = TRUE;
201 } else {
202 any_success = TRUE;
203 }
204 }
205
206 if (now) {
207 free(now);
208 }
209
210 if (any_failure) {
211 return (any_success? -1 : -2);
212 }
213 return pcmk_ok;
214 }
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231 int
232 lrmd_send_attribute_alert(lrmd_t *lrmd, const GList *alert_list,
233 const char *node, uint32_t nodeid,
234 const char *attr_name, const char *attr_value)
235 {
236 int rc = pcmk_ok;
237 lrmd_key_value_t *params = NULL;
238
239 if (lrmd == NULL) {
240 return -2;
241 }
242
243 params = alert_key2param(params, PCMK__alert_key_node, node);
244 params = alert_key2param_int(params, PCMK__alert_key_nodeid, nodeid);
245 params = alert_key2param(params, PCMK__alert_key_attribute_name, attr_name);
246 params = alert_key2param(params, PCMK__alert_key_attribute_value,
247 attr_value);
248
249 rc = exec_alert_list(lrmd, alert_list, pcmk__alert_attribute, attr_name,
250 params);
251 lrmd_key_value_freeall(params);
252 return rc;
253 }
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269 int
270 lrmd_send_node_alert(lrmd_t *lrmd, const GList *alert_list,
271 const char *node, uint32_t nodeid, const char *state)
272 {
273 int rc = pcmk_ok;
274 lrmd_key_value_t *params = NULL;
275
276 if (lrmd == NULL) {
277 return -2;
278 }
279
280 params = alert_key2param(params, PCMK__alert_key_node, node);
281 params = alert_key2param(params, PCMK__alert_key_desc, state);
282 params = alert_key2param_int(params, PCMK__alert_key_nodeid, nodeid);
283
284 rc = exec_alert_list(lrmd, alert_list, pcmk__alert_node, NULL, params);
285 lrmd_key_value_freeall(params);
286 return rc;
287 }
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304 int
305 lrmd_send_fencing_alert(lrmd_t *lrmd, const GList *alert_list,
306 const char *target, const char *task, const char *desc,
307 int op_rc)
308 {
309 int rc = pcmk_ok;
310 lrmd_key_value_t *params = NULL;
311
312 if (lrmd == NULL) {
313 return -2;
314 }
315
316 params = alert_key2param(params, PCMK__alert_key_node, target);
317 params = alert_key2param(params, PCMK__alert_key_task, task);
318 params = alert_key2param(params, PCMK__alert_key_desc, desc);
319 params = alert_key2param_int(params, PCMK__alert_key_rc, op_rc);
320
321 rc = exec_alert_list(lrmd, alert_list, pcmk__alert_fencing, NULL, params);
322 lrmd_key_value_freeall(params);
323 return rc;
324 }
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339 int
340 lrmd_send_resource_alert(lrmd_t *lrmd, const GList *alert_list,
341 const char *node, const lrmd_event_data_t *op)
342 {
343 int rc = pcmk_ok;
344 int target_rc = pcmk_ok;
345 lrmd_key_value_t *params = NULL;
346
347 if (lrmd == NULL) {
348 return -2;
349 }
350
351 target_rc = rsc_op_expected_rc(op);
352 if ((op->interval_ms == 0) && (target_rc == op->rc)
353 && pcmk__str_eq(op->op_type, PCMK_ACTION_MONITOR, pcmk__str_casei)) {
354
355
356
357
358
359
360 return pcmk_ok;
361 }
362
363 params = alert_key2param(params, PCMK__alert_key_node, node);
364 params = alert_key2param(params, PCMK__alert_key_rsc, op->rsc_id);
365 params = alert_key2param(params, PCMK__alert_key_task, op->op_type);
366 params = alert_key2param_ms(params, PCMK__alert_key_interval,
367 op->interval_ms);
368 params = alert_key2param_int(params, PCMK__alert_key_target_rc, target_rc);
369 params = alert_key2param_int(params, PCMK__alert_key_status, op->op_status);
370 params = alert_key2param_int(params, PCMK__alert_key_rc, op->rc);
371
372
373
374
375 if ((op->op_status == PCMK_EXEC_TIMEOUT) && (op->exec_time == 0)) {
376 params = alert_key2param_int(params, PCMK__alert_key_exec_time,
377 op->timeout);
378 } else {
379 params = alert_key2param_int(params, PCMK__alert_key_exec_time,
380 op->exec_time);
381 }
382
383 if (op->op_status == PCMK_EXEC_DONE) {
384 params = alert_key2param(params, PCMK__alert_key_desc,
385 crm_exit_str((crm_exit_t) op->rc));
386 } else {
387 params = alert_key2param(params, PCMK__alert_key_desc,
388 pcmk_exec_status_str(op->op_status));
389 }
390
391 rc = exec_alert_list(lrmd, alert_list, pcmk__alert_resource, NULL, params);
392 lrmd_key_value_freeall(params);
393 return rc;
394 }